Repository navigation
Expand file tree
/
Copy pathconsts.py
More file actions
501 lines (430 loc) · 18.8 KB
/
Copy pathconsts.py
File metadata and controls
501 lines (430 loc) · 18.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Defines constants used across the server."""
import os
from loguru import logger
# Service constants
DEFAULT_REGION = 'us-east-1'
DEFAULT_OMICS_SERVICE_NAME = 'omics'
DEFAULT_STORAGE_TYPE = 'DYNAMIC'
try:
DEFAULT_MAX_RESULTS = int(os.environ.get('HEALTHOMICS_DEFAULT_MAX_RESULTS', '100'))
except ValueError:
logger.warning(
'Invalid value for HEALTHOMICS_DEFAULT_MAX_RESULTS environment variable. '
'Using default value of 100.'
)
DEFAULT_MAX_RESULTS = 100
# Supported regions (as of June 2025)
# These are hardcoded as a fallback in case the boto3 session region query fails
HEALTHOMICS_SUPPORTED_REGIONS = [
'ap-southeast-1',
'eu-central-1',
'eu-west-1',
'eu-west-2',
'il-central-1',
'us-east-1',
'us-west-2',
]
# ECR Constants
HEALTHOMICS_PRINCIPAL = 'omics.amazonaws.com'
ECR_REQUIRED_REGISTRY_ACTIONS = ['ecr:CreateRepository', 'ecr:BatchImportUpstreamImage']
ECR_REQUIRED_REPOSITORY_ACTIONS = ['ecr:BatchGetImage', 'ecr:GetDownloadUrlForLayer']
# Default ECR repository prefixes
DEFAULT_ECR_PREFIXES = {
'docker-hub': 'docker-hub',
'quay': 'quay',
'ecr-public': 'ecr-public',
}
# Storage types
STORAGE_TYPE_STATIC = 'STATIC'
STORAGE_TYPE_DYNAMIC = 'DYNAMIC'
STORAGE_TYPES = [STORAGE_TYPE_STATIC, STORAGE_TYPE_DYNAMIC]
# Cache behaviors
CACHE_BEHAVIOR_ALWAYS = 'CACHE_ALWAYS'
CACHE_BEHAVIOR_ON_FAILURE = 'CACHE_ON_FAILURE'
CACHE_BEHAVIORS = [CACHE_BEHAVIOR_ALWAYS, CACHE_BEHAVIOR_ON_FAILURE]
# Scratch storage modes
SCRATCH_STORAGE_MODE_LOCAL = 'LOCAL'
SCRATCH_STORAGE_MODE_SHARED = 'SHARED'
SCRATCH_STORAGE_MODES = [SCRATCH_STORAGE_MODE_LOCAL, SCRATCH_STORAGE_MODE_SHARED]
# MCP server default scratch storage mode (diverges from the HealthOmics API default of SHARED)
DEFAULT_SCRATCH_STORAGE_MODE = SCRATCH_STORAGE_MODE_LOCAL
# Session policy (inline IAM policy JSON scoping down the run role)
SESSION_POLICY_MAX_LENGTH = 2048
# Run log levels (controls engine log capture to CloudWatch)
RUN_LOG_LEVEL_OFF = 'OFF'
RUN_LOG_LEVEL_FATAL = 'FATAL'
RUN_LOG_LEVEL_ERROR = 'ERROR'
RUN_LOG_LEVEL_ALL = 'ALL'
RUN_LOG_LEVELS = [
RUN_LOG_LEVEL_OFF,
RUN_LOG_LEVEL_FATAL,
RUN_LOG_LEVEL_ERROR,
RUN_LOG_LEVEL_ALL,
]
# Run output URI prefix modes (controls the output path layout under outputUri)
OUTPUT_URI_PREFIX_MODE_SERVICE_DEFINED = 'SERVICE_DEFINED'
OUTPUT_URI_PREFIX_MODE_NONE_WITH_OVERWRITE = 'NONE_WITH_OVERWRITE'
OUTPUT_URI_PREFIX_MODES = [
OUTPUT_URI_PREFIX_MODE_SERVICE_DEFINED,
OUTPUT_URI_PREFIX_MODE_NONE_WITH_OVERWRITE,
]
# Run statuses
RUN_STATUS_PENDING = 'PENDING'
RUN_STATUS_STARTING = 'STARTING'
RUN_STATUS_RUNNING = 'RUNNING'
RUN_STATUS_COMPLETED = 'COMPLETED'
RUN_STATUS_FAILED = 'FAILED'
RUN_STATUS_CANCELLED = 'CANCELLED'
RUN_STATUSES = [
RUN_STATUS_PENDING,
RUN_STATUS_STARTING,
RUN_STATUS_RUNNING,
RUN_STATUS_COMPLETED,
RUN_STATUS_FAILED,
RUN_STATUS_CANCELLED,
]
# Workflow engine types
WORKFLOW_ENGINES = ['WDL', 'NEXTFLOW', 'CWL', 'WDL_LENIENT']
# Accelerator types
ACCELERATOR_TYPE_GPU = 'GPU'
ACCELERATOR_TYPES = [ACCELERATOR_TYPE_GPU]
# Workflow types for GetWorkflow
GET_WORKFLOW_TYPES = ['PRIVATE', 'READY2RUN']
# Export types
EXPORT_TYPE_DEFINITION = 'DEFINITION'
EXPORT_TYPE_README = 'README'
EXPORT_TYPES = [EXPORT_TYPE_DEFINITION, EXPORT_TYPE_README]
# Agent identification
AGENT_ENV = 'AGENT'
# Genomics file search configuration
GENOMICS_SEARCH_S3_BUCKETS_ENV = 'GENOMICS_SEARCH_S3_BUCKETS'
GENOMICS_SEARCH_MAX_CONCURRENT_ENV = 'GENOMICS_SEARCH_MAX_CONCURRENT'
GENOMICS_SEARCH_TIMEOUT_ENV = 'GENOMICS_SEARCH_TIMEOUT_SECONDS'
GENOMICS_SEARCH_ENABLE_HEALTHOMICS_ENV = 'GENOMICS_SEARCH_ENABLE_HEALTHOMICS'
GENOMICS_SEARCH_ENABLE_S3_TAG_SEARCH_ENV = 'GENOMICS_SEARCH_ENABLE_S3_TAG_SEARCH'
GENOMICS_SEARCH_MAX_TAG_BATCH_SIZE_ENV = 'GENOMICS_SEARCH_MAX_TAG_BATCH_SIZE'
GENOMICS_SEARCH_RESULT_CACHE_TTL_ENV = 'GENOMICS_SEARCH_RESULT_CACHE_TTL'
GENOMICS_SEARCH_TAG_CACHE_TTL_ENV = 'GENOMICS_SEARCH_TAG_CACHE_TTL'
# Default values for genomics search
DEFAULT_GENOMICS_SEARCH_MAX_CONCURRENT = 10
DEFAULT_GENOMICS_SEARCH_TIMEOUT = 300
DEFAULT_GENOMICS_SEARCH_ENABLE_HEALTHOMICS = True
DEFAULT_GENOMICS_SEARCH_ENABLE_S3_TAG_SEARCH = True
DEFAULT_GENOMICS_SEARCH_MAX_TAG_BATCH_SIZE = 100
DEFAULT_GENOMICS_SEARCH_RESULT_CACHE_TTL = 600
DEFAULT_GENOMICS_SEARCH_TAG_CACHE_TTL = 300
# Cache size limits - Maximum number of entries in the cache
DEFAULT_GENOMICS_SEARCH_MAX_FILE_CACHE_SIZE = 10000
DEFAULT_GENOMICS_SEARCH_MAX_TAG_CACHE_SIZE = 1000
DEFAULT_GENOMICS_SEARCH_MAX_RESULT_CACHE_SIZE = 100
DEFAULT_GENOMICS_SEARCH_MAX_PAGINATION_CACHE_SIZE = 50
# Cache cleanup behavior
DEFAULT_CACHE_CLEANUP_KEEP_RATIO = 0.8 # Keep at most 80% of entries when cleaning up by size
# Search limits and pagination
MAX_SEARCH_RESULTS_LIMIT = 10000 # Maximum allowed results per search
DEFAULT_HEALTHOMICS_PAGE_SIZE = 100 # Default pagination size for HealthOmics APIs
DEFAULT_S3_PAGE_SIZE = 1000 # Default pagination size for S3 operations
DEFAULT_RESULT_RANKER_FALLBACK_SIZE = 100 # Fallback size when max_results is invalid
# Rate limiting and performance
HEALTHOMICS_RATE_LIMIT_DELAY = 0.1 # Sleep delay between HealthOmics Storage API calls (10 TPS)
# Cache cleanup sweep probabilities for entries with expired TTLs (as percentages for clarity)
PAGINATION_CACHE_CLEANUP_PROBABILITY = 1 # 1% chance (1 in 100)
S3_CACHE_CLEANUP_PROBABILITY = 2 # 2% chance (1 in 50)
# Buffer size optimization thresholds
CURSOR_PAGINATION_BUFFER_THRESHOLD = 5000 # Use cursor pagination above this buffer size
CURSOR_PAGINATION_PAGE_THRESHOLD = 10 # Use cursor pagination above this page number
BUFFER_EFFICIENCY_LOW_THRESHOLD = 0.1 # 10% efficiency threshold
BUFFER_EFFICIENCY_HIGH_THRESHOLD = 0.5 # 50% efficiency threshold
# Buffer size complexity multipliers
COMPLEXITY_MULTIPLIER_FILE_TYPE_FILTER = 0.8 # Reduce complexity when file type is filtered
COMPLEXITY_MULTIPLIER_ASSOCIATED_FILES = 1.2 # Increase complexity for associated files
COMPLEXITY_MULTIPLIER_BUFFER_OVERFLOW = 1.5 # Increase when buffer overflows occur
COMPLEXITY_MULTIPLIER_LOW_EFFICIENCY = 2.0 # Increase when efficiency is low
COMPLEXITY_MULTIPLIER_HIGH_EFFICIENCY = 0.8 # Decrease when efficiency is high
# Pattern matching thresholds and multipliers
FUZZY_MATCH_THRESHOLD = 0.6 # Minimum similarity for fuzzy matches
MULTIPLE_MATCH_BONUS_MULTIPLIER = 1.2 # 20% bonus for multiple pattern matches
TAG_MATCH_PENALTY_MULTIPLIER = 0.9 # 10% penalty for tag matches vs path matches
SUBSTRING_MATCH_MAX_MULTIPLIER = 0.8 # Maximum score multiplier for substring matches
FUZZY_MATCH_MAX_MULTIPLIER = 0.6 # Maximum score multiplier for fuzzy matches
# Match quality score thresholds
MATCH_QUALITY_EXCELLENT_THRESHOLD = 0.8
MATCH_QUALITY_GOOD_THRESHOLD = 0.6
MATCH_QUALITY_FAIR_THRESHOLD = 0.4
# Match quality labels
MATCH_QUALITY_EXCELLENT = 'excellent'
MATCH_QUALITY_GOOD = 'good'
MATCH_QUALITY_FAIR = 'fair'
MATCH_QUALITY_POOR = 'poor'
# Unit conversion constants
BYTES_PER_KILOBYTE = 1024
MILLISECONDS_PER_SECOND = 1000.0
# HealthOmics status constants
HEALTHOMICS_STATUS_ACTIVE = 'ACTIVE'
# HealthOmics storage class constants
HEALTHOMICS_STORAGE_CLASS_MANAGED = 'MANAGED'
# Storage tier constants
STORAGE_TIER_HOT = 'hot'
STORAGE_TIER_WARM = 'warm'
STORAGE_TIER_COLD = 'cold'
STORAGE_TIER_UNKNOWN = 'unknown'
# S3 storage class constants
S3_STORAGE_CLASS_STANDARD = 'STANDARD'
S3_STORAGE_CLASS_REDUCED_REDUNDANCY = 'REDUCED_REDUNDANCY'
S3_STORAGE_CLASS_STANDARD_IA = 'STANDARD_IA'
S3_STORAGE_CLASS_ONEZONE_IA = 'ONEZONE_IA'
S3_STORAGE_CLASS_INTELLIGENT_TIERING = 'INTELLIGENT_TIERING'
S3_STORAGE_CLASS_GLACIER = 'GLACIER'
S3_STORAGE_CLASS_DEEP_ARCHIVE = 'DEEP_ARCHIVE'
S3_STORAGE_CLASS_OUTPOSTS = 'OUTPOSTS'
S3_STORAGE_CLASS_GLACIER_IR = 'GLACIER_IR'
# Error messages
ERROR_INVALID_ENGINE = 'Invalid engine. Must be one of: {}'
ERROR_INVALID_ACCELERATOR = 'Invalid accelerator. Must be one of: {}'
ERROR_INVALID_WORKFLOW_TYPE = 'Invalid workflow type. Must be one of: {}'
ERROR_INVALID_EXPORT_TYPE = 'Invalid export type. Must be one of: {}'
ERROR_INVALID_STORAGE_TYPE = 'Invalid storage type. Must be one of: {}'
ERROR_INVALID_CACHE_BEHAVIOR = 'Invalid cache behavior. Must be one of: {}'
ERROR_INVALID_SCRATCH_STORAGE_MODE = "Invalid scratch storage mode '{}'. Must be one of: {}"
ERROR_INVALID_RUN_LOG_LEVEL = 'Invalid log level. Must be one of: {}'
ERROR_INVALID_OUTPUT_URI_PREFIX_MODE = "'{}' is not a valid value. Must be one of: {}"
ERROR_INVALID_SESSION_POLICY = 'Invalid session policy: {}'
ERROR_INVALID_RUN_STATUS = 'Invalid run status. Must be one of: {}'
ERROR_STATIC_STORAGE_REQUIRES_CAPACITY = (
'Storage capacity is required when using STATIC storage type'
)
ERROR_NO_S3_BUCKETS_CONFIGURED = (
'No S3 bucket paths configured. Set the GENOMICS_SEARCH_S3_BUCKETS environment variable '
'with comma-separated S3 paths (e.g., "s3://bucket1/prefix1/,s3://bucket2/prefix2/")'
)
ERROR_INVALID_S3_BUCKET_PATH = (
'Invalid S3 bucket path: {}. Must start with "s3://" and contain a valid bucket name'
)
# Genomics file index patterns
# Maps primary file extensions to their associated index file extensions
GENOMICS_INDEX_PATTERNS = {
'.bam': ['.bam.bai', '.bai'],
'.cram': ['.cram.crai', '.crai'],
'.vcf': ['.vcf.tbi', '.tbi'],
'.vcf.gz': ['.vcf.gz.tbi', '.tbi'],
'.fasta': ['.fasta.fai', '.fai'],
'.fa': ['.fa.fai', '.fai'],
'.fna': ['.fna.fai', '.fai'],
}
# FASTQ paired-end read patterns
FASTQ_PAIR_PATTERNS = [
('_R1_', '_R2_'),
('_R1.', '_R2.'),
('_R2_', '_R1_'),
('_R2.', '_R1.'),
('_1.', '_2.'),
('_2.', '_1.'),
]
# FASTQ file extensions
FASTQ_EXTENSIONS = ['fastq', 'fq', 'fastq.gz', 'fq.gz']
# Run group constants
RUN_GROUP_MAX_NAME_LENGTH = 128
RUN_GROUP_MAX_RESOURCE_LIMIT = 100000
RUN_GROUP_ID_MAX_LENGTH = 18
# Content resolution defaults
CONTENT_RESOLVER_MAX_FILE_SIZE_ENV = 'CONTENT_RESOLVER_MAX_FILE_SIZE_MB'
DEFAULT_CONTENT_RESOLVER_MAX_FILE_SIZE_MB = 100 # 100 MB default
# Batch status constants
BATCH_STATUS_PENDING = 'PENDING'
BATCH_STATUS_SUBMITTING = 'SUBMITTING'
BATCH_STATUS_INPROGRESS = 'INPROGRESS'
BATCH_STATUS_STOPPING = 'STOPPING'
BATCH_STATUS_CANCELLED = 'CANCELLED'
BATCH_STATUS_PROCESSED = 'PROCESSED'
BATCH_STATUS_FAILED = 'FAILED'
BATCH_STATUS_RUNS_DELETING = 'RUNS_DELETING'
BATCH_STATUS_RUNS_DELETED = 'RUNS_DELETED'
BATCH_STATUSES = [
BATCH_STATUS_PENDING,
BATCH_STATUS_SUBMITTING,
BATCH_STATUS_INPROGRESS,
BATCH_STATUS_STOPPING,
BATCH_STATUS_CANCELLED,
BATCH_STATUS_PROCESSED,
BATCH_STATUS_FAILED,
BATCH_STATUS_RUNS_DELETING,
BATCH_STATUS_RUNS_DELETED,
]
# Cancellable batch statuses
BATCH_CANCELLABLE_STATUSES = [
BATCH_STATUS_PENDING,
BATCH_STATUS_SUBMITTING,
BATCH_STATUS_INPROGRESS,
]
# Deletable batch statuses (for DeleteRunBatch)
BATCH_RUN_DELETABLE_STATUSES = [
BATCH_STATUS_PROCESSED,
BATCH_STATUS_CANCELLED,
]
# Terminal batch statuses (for DeleteBatch)
BATCH_TERMINAL_STATUSES = [
BATCH_STATUS_PROCESSED,
BATCH_STATUS_FAILED,
BATCH_STATUS_CANCELLED,
BATCH_STATUS_RUNS_DELETED,
]
# Submission status constants
SUBMISSION_STATUS_SUCCESS = 'SUCCESS'
SUBMISSION_STATUS_FAILED = 'FAILED'
SUBMISSION_STATUS_CANCEL_SUCCESS = 'CANCEL_SUCCESS'
SUBMISSION_STATUS_CANCEL_FAILED = 'CANCEL_FAILED'
SUBMISSION_STATUS_DELETE_SUCCESS = 'DELETE_SUCCESS'
SUBMISSION_STATUS_DELETE_FAILED = 'DELETE_FAILED'
SUBMISSION_STATUSES = [
SUBMISSION_STATUS_SUCCESS,
SUBMISSION_STATUS_FAILED,
SUBMISSION_STATUS_CANCEL_SUCCESS,
SUBMISSION_STATUS_CANCEL_FAILED,
SUBMISSION_STATUS_DELETE_SUCCESS,
SUBMISSION_STATUS_DELETE_FAILED,
]
# Error messages for batch operations
ERROR_INVALID_BATCH_STATUS = 'Invalid batch status. Must be one of: {}'
ERROR_INVALID_SUBMISSION_STATUS = 'Invalid submission status. Must be one of: {}'
ERROR_BATCH_NOT_CANCELLABLE = 'Batch cannot be cancelled. Status must be one of: {}'
ERROR_BATCH_RUNS_NOT_DELETABLE = 'Batch runs cannot be deleted. Status must be one of: {}'
ERROR_BATCH_NOT_DELETABLE = 'Batch cannot be deleted. Status must be one of: {}'
ERROR_INVALID_BATCH_RUN_SETTINGS = (
'batchRunSettings must contain either inlineSettings or s3UriSettings, but not both'
)
# Networking modes
NETWORKING_MODE_RESTRICTED = 'RESTRICTED'
NETWORKING_MODE_VPC = 'VPC'
NETWORKING_MODES = [NETWORKING_MODE_RESTRICTED, NETWORKING_MODE_VPC]
# Configuration statuses
CONFIGURATION_STATUS_CREATING = 'CREATING'
CONFIGURATION_STATUS_ACTIVE = 'ACTIVE'
CONFIGURATION_STATUS_DELETING = 'DELETING'
CONFIGURATION_STATUS_DELETED = 'DELETED'
CONFIGURATION_STATUSES = [
CONFIGURATION_STATUS_CREATING,
CONFIGURATION_STATUS_ACTIVE,
CONFIGURATION_STATUS_DELETING,
CONFIGURATION_STATUS_DELETED,
]
# Configuration constraints
CONFIGURATION_NAME_MAX_LENGTH = 50
RESERVED_CONFIGURATION_NAMES = ['default']
# Error messages for configuration and networking operations
ERROR_INVALID_NETWORKING_MODE = 'Invalid networking mode. Must be one of: {}'
ERROR_VPC_MODE_REQUIRES_CONFIGURATION_NAME = (
'configuration_name is required when networking_mode is VPC'
)
ERROR_CONFIGURATION_NAME_REQUIRES_VPC_MODE = (
'configuration_name requires networking_mode to be VPC'
)
ERROR_RESERVED_CONFIGURATION_NAME = "Configuration name '{}' is reserved and cannot be used"
ERROR_CONFIGURATION_NAME_TOO_LONG = 'Configuration name exceeds maximum length of {} characters'
# Transport selection (Phase 1)
MCP_TRANSPORT_ENV = 'MCP_TRANSPORT'
MCP_HOST_ENV = 'MCP_HOST'
MCP_PORT_ENV = 'MCP_PORT'
MCP_PATH_ENV = 'MCP_PATH'
# Transport and network defaults (Phase 1)
DEFAULT_TRANSPORT = 'stdio'
DEFAULT_HTTP_HOST = '127.0.0.1' # Loopback_Address
DEFAULT_HTTP_PORT = 8000
DEFAULT_HTTP_PATH = '/mcp'
# Supported transports (Phase 1)
SUPPORTED_TRANSPORTS = ('stdio', 'streamable-http', 'sse')
NETWORK_TRANSPORTS = ('streamable-http', 'sse')
# Error messages for transport and network configuration (Phase 1)
ERROR_UNSUPPORTED_TRANSPORT = "Unsupported transport '{}'. Supported transports: {}"
ERROR_INVALID_PORT = "Invalid port '{}'. Port must be an integer in the range 1-65535."
ERROR_INVALID_HOST = "Invalid host '{}'. Must be a valid IPv4 address, IPv6 address, or hostname."
# Warning emitted when binding a network transport to a non-loopback host (Phase 1).
# Phase 1 performs no inbound authentication of its own; non-loopback exposure
# requires an external fronting authentication layer.
WARN_NON_LOOPBACK_EXPOSURE = (
"Binding network transport to non-loopback host '{}'. The server does not "
'perform inbound authentication; non-loopback exposure requires an external '
'fronting authentication layer (for example SigV4 via mcp-proxy-for-aws, a '
'reverse proxy, or an API gateway).'
)
# Multi-tenant selection (Phase 2)
MCP_MULTI_TENANT_ENV = 'MCP_MULTI_TENANT'
MCP_INBOUND_AUTH_ENV = 'MCP_INBOUND_AUTH'
# ARN of the role assumed by the inbound JWT-to-STS exchange mechanism (Phase 2).
# Required only when the 'jwt' inbound mechanism is enabled; supplied via this
# environment variable because the JWT exchange mechanism has no other source
# for the target role ARN.
MCP_JWT_ROLE_ARN_ENV = 'MCP_JWT_ROLE_ARN'
# Provider-controlled registry source for per-request role/ExternalId resolution
# (customer-account role assumption). Selects the RegistryRoleResolver; its value
# names exactly one backend, either a file-based JSON map (file:///path/map.json)
# or a DynamoDB table (dynamodb://table-name). Mutually exclusive with
# MCP_JWT_ROLE_ARN.
MCP_JWT_ROLE_REGISTRY_ENV = 'MCP_JWT_ROLE_REGISTRY'
# Optional session duration (in seconds) applied to the inbound JWT-to-STS
# AssumeRole exchange. When unset the exchange uses DEFAULT_JWT_SESSION_DURATION.
MCP_JWT_SESSION_DURATION_ENV = 'MCP_JWT_SESSION_DURATION'
# Session-duration bounds for the inbound JWT-to-STS AssumeRole exchange.
# The inclusive range mirrors the AWS STS AssumeRole DurationSeconds limits.
JWT_SESSION_DURATION_MIN = 900
JWT_SESSION_DURATION_MAX = 43200
DEFAULT_JWT_SESSION_DURATION = 3600
# Inbound authentication mechanisms (Phase 2).
# INBOUND_PRECEDENCE documents the deterministic order in which mechanisms apply.
INBOUND_MECHANISMS = ('sigv4', 'jwt', 'explicit')
INBOUND_PRECEDENCE = ('sigv4', 'jwt', 'explicit')
# Error messages for multi-tenant configuration (Phase 2)
ERROR_MULTI_TENANT_REQUIRES_NETWORK = (
'Multi-tenant mode is incompatible with the stdio transport. '
'Select a network transport (streamable-http or sse).'
)
ERROR_INVALID_MULTI_TENANT_VALUE = "Invalid multi-tenant value '{}'. Accepted values: {}"
ERROR_INVALID_INBOUND_AUTH = "Invalid inbound authentication mechanism '{}'. Accepted values: {}"
ERROR_MISSING_JWT_ROLE_ARN = (
"The 'jwt' inbound mechanism is enabled but no role ARN is configured. "
'Set the {} environment variable to the ARN of the role to assume.'
)
ERROR_MULTI_TENANT_REQUIRES_MECHANISM = (
'Multi-tenant mode is enabled but no inbound identity mechanisms are '
'configured. Select at least one mechanism ({}) via the --inbound-auth flag '
'or the {} environment variable; otherwise every inbound request would be '
'rejected.'
)
# Startup error messages for the customer-account role-assumption resolver surface.
# Both role-resolution sources configured is a conflict (fail fast at startup):
# the '{}' placeholders name the two conflicting sources (MCP_JWT_ROLE_ARN and
# MCP_JWT_ROLE_REGISTRY).
ERROR_CONFLICTING_ROLE_RESOLUTION_SOURCES = (
'Conflicting JWT role-resolution sources configured: both {} and {} are set. '
'Configure exactly one of them.'
)
# Invalid session duration: the first '{}' is the rejected value, the following
# two are the inclusive minimum and maximum of the accepted range.
ERROR_INVALID_JWT_SESSION_DURATION = (
"Invalid JWT session duration '{}'. Must be an integer within the inclusive "
'range {} to {} seconds.'
)
# The 'jwt' inbound mechanism is enabled but neither role-resolution source is
# configured. The two '{}' placeholders name the acceptable sources
# (MCP_JWT_ROLE_ARN for the static resolver and MCP_JWT_ROLE_REGISTRY for the
# registry resolver); exactly one of them must be set.
ERROR_MISSING_JWT_ROLE_SOURCE = (
"The 'jwt' inbound mechanism is enabled but no role-resolution source is "
'configured. Set exactly one of {} (a static role ARN) or {} (a registry '
'source) to select the role to assume.'
)
# An MCP_JWT_ROLE_REGISTRY value that names an unsupported source backend. The
# first '{}' is the env-var name and the second '{}' is the underlying reason.
ERROR_INVALID_JWT_ROLE_REGISTRY = 'Invalid {} value: {}'