This is page 703 of 717. Use http://codebase.md/awslabs/mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .devcontainer
│ └── devcontainer.json
├── .github
│ ├── actions
│ │ ├── build-and-push-container-image
│ │ │ └── action.yml
│ │ └── clear-space-ubuntu-latest-agressively
│ │ └── action.yml
│ ├── codecov.yml
│ ├── CODEOWNERS
│ ├── dependabot.yml
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── documentation.yml
│ │ ├── feature_request.yml
│ │ ├── rfc.yml
│ │ └── support_awslabs_mcp_servers.yml
│ ├── pull_request_template.md
│ ├── SECURITY
│ ├── SUPPORT
│ └── workflows
│ ├── aws-api-mcp-upgrade-version.yml
│ ├── bandit-requirements.txt
│ ├── bandit.yml
│ ├── cfn_nag.yml
│ ├── check-gh-pages-builds.yml
│ ├── check-license-header-hash.txt
│ ├── check-license-header-slash.txt
│ ├── check-license-header.json
│ ├── check-license-header.yml
│ ├── checkov.yml
│ ├── codeql.yml
│ ├── dependency-review-action.yml
│ ├── detect-secrets-requirements.txt
│ ├── gh-pages.yml
│ ├── merge-prevention.yml
│ ├── powershell.yml
│ ├── pre-commit-requirements.txt
│ ├── pre-commit.yml
│ ├── pull-request-lint.yml
│ ├── python.yml
│ ├── RELEASE_INSTRUCTIONS.md
│ ├── release-initiate-branch.yml
│ ├── release-merge-tag.yml
│ ├── release.py
│ ├── release.yml
│ ├── scanners.yml
│ ├── scorecard-analysis.yml
│ ├── semgrep-requirements.txt
│ ├── semgrep.yml
│ ├── stale.yml
│ ├── trivy.yml
│ └── typescript.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── .ruff.toml
├── .secrets.baseline
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DESIGN_GUIDELINES.md
├── DEVELOPER_GUIDE.md
├── docs
│ └── images
│ └── root-readme
│ ├── cline-api-provider-filled.png
│ ├── cline-chat-interface.png
│ ├── cline-custom-instructions.png
│ ├── cline-select-aws-profile.png
│ ├── cline-select-bedrock.png
│ ├── configure-mcp-servers.png
│ ├── install-cline-extension.png
│ ├── mcp-servers-installed.png
│ └── select-mcp-servers.png
├── docusaurus
│ ├── .gitignore
│ ├── docs
│ │ ├── installation.md
│ │ ├── intro.md
│ │ ├── samples
│ │ │ ├── index.md
│ │ │ ├── mcp-integration-with-kb.md
│ │ │ ├── mcp-integration-with-nova-canvas.md
│ │ │ └── stepfunctions-tool-mcp-server.md
│ │ ├── servers
│ │ │ ├── amazon-bedrock-agentcore-mcp-server.md
│ │ │ ├── amazon-keyspaces-mcp-server.md
│ │ │ ├── amazon-mq-mcp-server.md
│ │ │ ├── amazon-neptune-mcp-server.md
│ │ │ ├── amazon-qbusiness-anonymous-mcp-server.md
│ │ │ ├── amazon-qindex-mcp-server.md
│ │ │ ├── amazon-sns-sqs-mcp-server.md
│ │ │ ├── aurora-dsql-mcp-server.md
│ │ │ ├── aws-api-mcp-server.md
│ │ │ ├── aws-appsync-mcp-server.md
│ │ │ ├── aws-bedrock-custom-model-import-mcp-server.md
│ │ │ ├── aws-bedrock-data-automation-mcp-server.md
│ │ │ ├── aws-dataprocessing-mcp-server.md
│ │ │ ├── aws-diagram-mcp-server.md
│ │ │ ├── aws-documentation-mcp-server.md
│ │ │ ├── aws-healthomics-mcp-server.md
│ │ │ ├── aws-iot-sitewise-mcp-server.md
│ │ │ ├── aws-knowledge-mcp-server.md
│ │ │ ├── aws-location-mcp-server.md
│ │ │ ├── aws-msk-mcp-server.md
│ │ │ ├── aws-pricing-mcp-server.md
│ │ │ ├── aws-serverless-mcp-server.md
│ │ │ ├── aws-support-mcp-server.md
│ │ │ ├── bedrock-kb-retrieval-mcp-server.md
│ │ │ ├── billing-cost-management-mcp-server.md
│ │ │ ├── ccapi-mcp-server.md
│ │ │ ├── cdk-mcp-server.md
│ │ │ ├── cfn-mcp-server.md
│ │ │ ├── cloudtrail-mcp-server.md
│ │ │ ├── cloudwatch-applicationsignals-mcp-server.md
│ │ │ ├── cloudwatch-mcp-server.md
│ │ │ ├── code-doc-gen-mcp-server.md
│ │ │ ├── core-mcp-server.md
│ │ │ ├── cost-explorer-mcp-server.md
│ │ │ ├── document-loader-mcp-server.md
│ │ │ ├── documentdb-mcp-server.md
│ │ │ ├── dynamodb-mcp-server.md
│ │ │ ├── ecs-mcp-server.md
│ │ │ ├── eks-mcp-server.md
│ │ │ ├── elasticache-mcp-server.md
│ │ │ ├── finch-mcp-server.md
│ │ │ ├── frontend-mcp-server.md
│ │ │ ├── git-repo-research-mcp-server.md
│ │ │ ├── healthlake-mcp-server.md
│ │ │ ├── iam-mcp-server.md
│ │ │ ├── kendra-index-mcp-server.md
│ │ │ ├── lambda-tool-mcp-server.md
│ │ │ ├── memcached-mcp-server.md
│ │ │ ├── mysql-mcp-server.md
│ │ │ ├── nova-canvas-mcp-server.md
│ │ │ ├── openapi-mcp-server.md
│ │ │ ├── postgres-mcp-server.md
│ │ │ ├── prometheus-mcp-server.md
│ │ │ ├── redshift-mcp-server.md
│ │ │ ├── s3-tables-mcp-server.md
│ │ │ ├── stepfunctions-tool-mcp-server.md
│ │ │ ├── syntheticdata-mcp-server.md
│ │ │ ├── terraform-mcp-server.md
│ │ │ ├── timestream-for-influxdb-mcp-server.md
│ │ │ ├── valkey-mcp-server.md
│ │ │ └── well-architected-security-mcp-server.mdx
│ │ └── vibe_coding.md
│ ├── docusaurus.config.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── sidebars.ts
│ ├── src
│ │ ├── components
│ │ │ ├── HomepageFeatures
│ │ │ │ └── styles.module.css
│ │ │ └── ServerCards
│ │ │ ├── index.tsx
│ │ │ └── styles.module.css
│ │ ├── css
│ │ │ ├── custom.css
│ │ │ └── doc-override.css
│ │ └── pages
│ │ ├── index.module.css
│ │ └── servers.tsx
│ ├── static
│ │ ├── .nojekyll
│ │ ├── assets
│ │ │ ├── icons
│ │ │ │ ├── activity.svg
│ │ │ │ ├── book-open.svg
│ │ │ │ ├── cpu.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── dollar-sign.svg
│ │ │ │ ├── help-circle.svg
│ │ │ │ ├── key.svg
│ │ │ │ ├── server.svg
│ │ │ │ ├── share-2.svg
│ │ │ │ ├── tool.svg
│ │ │ │ └── zap.svg
│ │ │ └── server-cards.json
│ │ └── img
│ │ ├── aws-logo.svg
│ │ └── logo.png
│ └── tsconfig.json
├── LICENSE
├── NOTICE
├── README.md
├── samples
│ ├── mcp-integration-with-kb
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── assets
│ │ │ └── simplified-mcp-flow-diagram.png
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── chat_bedrock_st.py
│ │ └── uv.lock
│ ├── mcp-integration-with-nova-canvas
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── image_generator_st.py
│ │ └── uv.lock
│ ├── README.md
│ └── stepfunctions-tool-mcp-server
│ ├── README.md
│ └── sample_state_machines
│ ├── customer-create
│ │ └── app.py
│ ├── customer-id-from-email
│ │ └── app.py
│ ├── customer-info-from-id
│ │ └── app.py
│ └── template.yml
├── scripts
│ ├── README.md
│ └── verify_package_name.py
├── src
│ ├── amazon-bedrock-agentcore-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_bedrock_agentcore_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache.py
│ │ │ ├── doc_fetcher.py
│ │ │ ├── indexer.py
│ │ │ ├── text_processor.py
│ │ │ └── url_validator.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── SECURITY.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_config.py
│ │ │ ├── test_doc_fetcher.py
│ │ │ ├── test_indexer.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_text_processor.py
│ │ │ └── test_url_validator.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-kendra-index-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_kendra_index_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-keyspaces-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_keyspaces_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── services.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_analysis_service.py
│ │ │ ├── test_server.py
│ │ │ └── test_services.py
│ │ └── uv.lock
│ ├── amazon-mq-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_mq_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_mcp_generator.py
│ │ │ ├── consts.py
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── admin.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── doc
│ │ │ │ │ ├── rabbitmq_broker_sizing_guide.md
│ │ │ │ │ ├── rabbitmq_performance_optimization_best_practice.md
│ │ │ │ │ ├── rabbitmq_production_deployment_guidelines.md
│ │ │ │ │ ├── rabbitmq_quorum_queue_migration_guide.md
│ │ │ │ │ └── rabbitmq_setup_best_practice.md
│ │ │ │ ├── handlers.py
│ │ │ │ └── module.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── example
│ │ │ └── sample_mcp_q_cli.json
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_admin.py
│ │ │ │ ├── test_connection.py
│ │ │ │ ├── test_handlers.py
│ │ │ │ └── test_module.py
│ │ │ ├── test_aws_service_mcp_generator.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-neptune-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_neptune_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── exceptions.py
│ │ │ ├── graph_store
│ │ │ │ ├── __init__.py
│ │ │ │ ├── analytics.py
│ │ │ │ ├── base.py
│ │ │ │ └── database.py
│ │ │ ├── models.py
│ │ │ ├── neptune.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_analytics.py
│ │ │ ├── test_database.py
│ │ │ ├── test_exceptions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_neptune.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qbusiness-anonymous-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qbusiness_anonymous_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qindex-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qindex_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_clients.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── amazon-sns-sqs-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_sns_sqs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── consts.py
│ │ │ ├── generator.py
│ │ │ ├── server.py
│ │ │ ├── sns.py
│ │ │ └── sqs.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── print_tools.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_common.py
│ │ │ ├── test_generator.py
│ │ │ ├── test_server.py
│ │ │ ├── test_sns.py
│ │ │ └── test_sqs.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aurora-dsql-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aurora_dsql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection_reuse.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_profile_option.py
│ │ │ ├── test_readonly_enforcement.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-api-mcp-server
│ │ ├── .gitattributes
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_api_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent_scripts
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── manager.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── registry
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── application-failure-troubleshooting.script.md
│ │ │ │ │ ├── cloudtral-mutli-region-setup.script.md
│ │ │ │ │ ├── create_amazon_aurora_db_cluster_with_instances.script.md
│ │ │ │ │ ├── lambda-timeout-debugging.script.md
│ │ │ │ │ ├── scripts_format.md
│ │ │ │ │ └── troubleshoot-permissions-with-cloudtrail-events.script.md
│ │ │ │ ├── aws
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── driver.py
│ │ │ │ │ ├── pagination.py
│ │ │ │ │ ├── regions.py
│ │ │ │ │ ├── service.py
│ │ │ │ │ └── services.py
│ │ │ │ ├── common
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── command_metadata.py
│ │ │ │ │ ├── command.py
│ │ │ │ │ ├── config.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_operations.py
│ │ │ │ │ ├── file_system_controls.py
│ │ │ │ │ ├── helpers.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── data
│ │ │ │ │ └── api_metadata.json
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── read_only_operations_list.py
│ │ │ │ ├── parser
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── custom_validators
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── botocore_param_validator.py
│ │ │ │ │ │ ├── ec2_validator.py
│ │ │ │ │ │ └── ssm_validator.py
│ │ │ │ │ ├── interpretation.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ └── parser.py
│ │ │ │ ├── py.typed
│ │ │ │ └── security
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_api_customization.json
│ │ │ │ └── policy.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ └── http_header_validation_middleware.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── DEPLOYMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── agent_scripts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_manager.py
│ │ │ │ └── test_registry
│ │ │ │ ├── another_valid_script.script.md
│ │ │ │ ├── test_script.script.md
│ │ │ │ └── valid_script.script.md
│ │ │ ├── aws
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_driver.py
│ │ │ │ ├── test_pagination.py
│ │ │ │ ├── test_service.py
│ │ │ │ └── test_services.py
│ │ │ ├── common
│ │ │ │ ├── test_command.py
│ │ │ │ ├── test_config.py
│ │ │ │ ├── test_file_operations.py
│ │ │ │ ├── test_file_system_controls.py
│ │ │ │ ├── test_file_validation.py
│ │ │ │ └── test_helpers.py
│ │ │ ├── fixtures.py
│ │ │ ├── history_handler.py
│ │ │ ├── metadata
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_read_only_operations_list.py
│ │ │ ├── middleware
│ │ │ │ └── test_http_header_validation_middleware.py
│ │ │ ├── parser
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_file_path_detection.py
│ │ │ │ ├── test_lexer.py
│ │ │ │ ├── test_parser_customizations.py
│ │ │ │ └── test_parser.py
│ │ │ ├── test_security_policy.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-appsync-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_appsync_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── decorators.py
│ │ │ ├── helpers.py
│ │ │ ├── operations
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ └── validators.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_all_create_tools_write_protection.py
│ │ │ ├── test_create_api_cache.py
│ │ │ ├── test_create_api_key.py
│ │ │ ├── test_create_api.py
│ │ │ ├── test_create_channel_namespace.py
│ │ │ ├── test_create_datasource_tool.py
│ │ │ ├── test_create_datasource.py
│ │ │ ├── test_create_domain_name.py
│ │ │ ├── test_create_function.py
│ │ │ ├── test_create_graphql_api.py
│ │ │ ├── test_create_resolver.py
│ │ │ ├── test_create_schema_tool.py
│ │ │ ├── test_create_schema.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validators.py
│ │ │ └── test_write_operation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-custom-model-import-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_custom_model_import_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── prompts.py
│ │ │ ├── server.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── imported_model_service.py
│ │ │ │ └── model_import_service.py
│ │ │ ├── tools
│ │ │ │ ├── create_model_import_job.py
│ │ │ │ ├── delete_imported_model.py
│ │ │ │ ├── get_imported_model.py
│ │ │ │ ├── get_model_import_job.py
│ │ │ │ ├── list_imported_models.py
│ │ │ │ └── list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ └── matching.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── services
│ │ │ │ ├── test_imported_model_service.py
│ │ │ │ └── test_model_import_service.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_llm_context.py
│ │ │ ├── test_prompts.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── test_create_model_import_job.py
│ │ │ │ ├── test_delete_imported_model.py
│ │ │ │ ├── test_get_imported_model.py
│ │ │ │ ├── test_get_model_import_job.py
│ │ │ │ ├── test_list_imported_models.py
│ │ │ │ └── test_list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── test_aws.py
│ │ │ ├── test_config.py
│ │ │ └── test_matching.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-data-automation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_data_automation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── helpers.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-dataprocessing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_dataprocessing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── data_catalog_database_manager.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ └── data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── athena_data_catalog_handler.py
│ │ │ │ │ ├── athena_query_handler.py
│ │ │ │ │ └── athena_workgroup_handler.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── emr_ec2_cluster_handler.py
│ │ │ │ │ ├── emr_ec2_instance_handler.py
│ │ │ │ │ └── emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── crawler_handler.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ ├── glue_commons_handler.py
│ │ │ │ ├── glue_etl_handler.py
│ │ │ │ ├── interactive_sessions_handler.py
│ │ │ │ └── worklows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena_models.py
│ │ │ │ ├── common_resource_models.py
│ │ │ │ ├── data_catalog_models.py
│ │ │ │ ├── emr_models.py
│ │ │ │ └── glue_models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── consts.py
│ │ │ ├── logging_helper.py
│ │ │ └── sql_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_data_catalog_database_manager.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ └── test_data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_athena_data_catalog_handler.py
│ │ │ │ │ ├── test_athena_query_handler.py
│ │ │ │ │ ├── test_athena_workgroup_handler.py
│ │ │ │ │ └── test_custom_tags_athena.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── test_common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_custom_tags_emr.py
│ │ │ │ │ ├── test_emr_ec2_cluster_handler.py
│ │ │ │ │ ├── test_emr_ec2_instance_handler.py
│ │ │ │ │ └── test_emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_crawler_handler.py
│ │ │ │ ├── test_custom_tags_glue.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ ├── test_glue_commons_handler.py
│ │ │ │ ├── test_glue_etl_handler.py
│ │ │ │ ├── test_glue_interactive_sessions_handler.py
│ │ │ │ └── test_glue_workflows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_athena_models.py
│ │ │ │ ├── test_common_resource_models.py
│ │ │ │ ├── test_data_catalog_models.py
│ │ │ │ ├── test_emr_models.py
│ │ │ │ ├── test_glue_models.py
│ │ │ │ ├── test_interactive_sessions_models.py
│ │ │ │ └── test_workflows_models.py
│ │ │ ├── test_init.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_custom_tags.py
│ │ │ ├── test_logging_helper.py
│ │ │ └── test_sql_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-diagram-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_diagram_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── diagrams_tools.py
│ │ │ ├── models.py
│ │ │ ├── scanner.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ └── example_diagrams
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_example.py
│ │ │ │ ├── flow_example.py
│ │ │ │ └── sequence_example.py
│ │ │ ├── test_diagrams.py
│ │ │ ├── test_models.py
│ │ │ ├── test_sarif_fix.py
│ │ │ ├── test_scanner.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-documentation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_documentation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── server_aws_cn.py
│ │ │ ├── server_aws.py
│ │ │ ├── server_utils.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── basic-usage.gif
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── constants.py
│ │ │ ├── resources
│ │ │ │ └── lambda_sns_raw.html
│ │ │ ├── test_aws_cn_get_available_services_live.py
│ │ │ ├── test_aws_cn_read_documentation_live.py
│ │ │ ├── test_aws_read_documentation_live.py
│ │ │ ├── test_aws_recommend_live.py
│ │ │ ├── test_aws_search_live.py
│ │ │ ├── test_integ_basic.py
│ │ │ ├── test_metadata_handling.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server_aws_cn.py
│ │ │ ├── test_server_aws.py
│ │ │ ├── test_server_utils.py
│ │ │ ├── test_server.py
│ │ │ └── test_util.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-healthomics-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_healthomics_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── core.py
│ │ │ │ ├── s3.py
│ │ │ │ └── search.py
│ │ │ ├── search
│ │ │ │ ├── __init__.py
│ │ │ │ ├── file_association_engine.py
│ │ │ │ ├── file_type_detector.py
│ │ │ │ ├── genomics_search_orchestrator.py
│ │ │ │ ├── healthomics_search_engine.py
│ │ │ │ ├── json_response_builder.py
│ │ │ │ ├── pattern_matcher.py
│ │ │ │ ├── result_ranker.py
│ │ │ │ ├── s3_search_engine.py
│ │ │ │ └── scoring_engine.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── genomics_file_search.py
│ │ │ │ ├── helper_tools.py
│ │ │ │ ├── run_analysis.py
│ │ │ │ ├── troubleshooting.py
│ │ │ │ ├── workflow_analysis.py
│ │ │ │ ├── workflow_execution.py
│ │ │ │ ├── workflow_linting.py
│ │ │ │ └── workflow_management.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_utils.py
│ │ │ ├── s3_utils.py
│ │ │ ├── search_config.py
│ │ │ └── validation_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── docs
│ │ │ └── workflow_linting.md
│ │ ├── LICENSE
│ │ ├── MCP_INSPECTOR_SETUP.md
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── fixtures
│ │ │ │ └── genomics_test_data.py
│ │ │ ├── INTEGRATION_TESTS_README.md
│ │ │ ├── QUICK_REFERENCE.md
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_file_association_engine.py
│ │ │ ├── test_file_type_detector.py
│ │ │ ├── test_genomics_file_search_integration_working.py
│ │ │ ├── test_genomics_search_orchestrator.py
│ │ │ ├── test_healthomics_search_engine.py
│ │ │ ├── test_helper_tools.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_integration_framework.py
│ │ │ ├── test_json_response_builder.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_pagination.py
│ │ │ ├── test_pattern_matcher.py
│ │ │ ├── test_performance_comparison.py
│ │ │ ├── test_result_ranker.py
│ │ │ ├── test_run_analysis.py
│ │ │ ├── test_s3_file_model.py
│ │ │ ├── test_s3_search_engine.py
│ │ │ ├── test_s3_utils.py
│ │ │ ├── test_scoring_engine.py
│ │ │ ├── test_search_config.py
│ │ │ ├── test_server.py
│ │ │ ├── test_troubleshooting.py
│ │ │ ├── test_validation_utils.py
│ │ │ ├── test_workflow_analysis.py
│ │ │ ├── test_workflow_execution.py
│ │ │ ├── test_workflow_linting.py
│ │ │ ├── test_workflow_management.py
│ │ │ ├── test_workflow_tools.py
│ │ │ └── TESTING_FRAMEWORK.md
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-iot-sitewise-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_iot_sitewise_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── models
│ │ │ │ ├── computation_data_models.py
│ │ │ │ └── metadata_transfer_data_models.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── anomaly_detection_workflow.py
│ │ │ │ ├── asset_hierarchy.py
│ │ │ │ ├── bulk_import_workflow.py
│ │ │ │ ├── data_exploration.py
│ │ │ │ └── data_ingestion.py
│ │ │ ├── server.py
│ │ │ ├── tool_metadata.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── sitewise_access.py
│ │ │ │ ├── sitewise_asset_models.py
│ │ │ │ ├── sitewise_assets.py
│ │ │ │ ├── sitewise_computation_models.py
│ │ │ │ ├── sitewise_data.py
│ │ │ │ ├── sitewise_executions.py
│ │ │ │ ├── sitewise_gateways.py
│ │ │ │ ├── sitewise_metadata_transfer.py
│ │ │ │ └── timestamp_tools.py
│ │ │ ├── validation_utils.py
│ │ │ └── validation.py
│ │ ├── CHANGELOG.md
│ │ ├── DEVELOPMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ └── wind_farm_example.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_server.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── models
│ │ │ │ ├── test_computation_data_models.py
│ │ │ │ └── test_metadata_transfer_data_models.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validation_utils.py
│ │ │ ├── test_validation.py
│ │ │ └── tools
│ │ │ ├── test_sitewise_access.py
│ │ │ ├── test_sitewise_asset_models.py
│ │ │ ├── test_sitewise_assets.py
│ │ │ ├── test_sitewise_computation_models.py
│ │ │ ├── test_sitewise_data.py
│ │ │ ├── test_sitewise_executions.py
│ │ │ ├── test_sitewise_gateways.py
│ │ │ ├── test_sitewise_metadata_transfer.py
│ │ │ └── test_timestamp_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-knowledge-mcp-server
│ │ └── README.md
│ ├── aws-location-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_location_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_server_integration.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-msk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_msk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── common_functions
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client_manager.py
│ │ │ │ └── common_functions.py
│ │ │ ├── logs_and_telemetry
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cluster_metrics_tools.py
│ │ │ │ ├── list_customer_iam_access.py
│ │ │ │ └── metric_config.py
│ │ │ ├── mutate_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_associate_scram_secret.py
│ │ │ │ ├── batch_disassociate_scram_secret.py
│ │ │ │ ├── create_cluster_v2.py
│ │ │ │ ├── put_cluster_policy.py
│ │ │ │ ├── reboot_broker.py
│ │ │ │ ├── update_broker_count.py
│ │ │ │ ├── update_broker_storage.py
│ │ │ │ ├── update_broker_type.py
│ │ │ │ ├── update_cluster_configuration.py
│ │ │ │ ├── update_monitoring.py
│ │ │ │ └── update_security.py
│ │ │ ├── mutate_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_configuration.py
│ │ │ │ ├── tag_resource.py
│ │ │ │ ├── untag_resource.py
│ │ │ │ └── update_configuration.py
│ │ │ ├── mutate_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_vpc_connection.py
│ │ │ │ ├── delete_vpc_connection.py
│ │ │ │ └── reject_client_vpc_connection.py
│ │ │ ├── read_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_cluster_operation.py
│ │ │ │ ├── describe_cluster.py
│ │ │ │ ├── get_bootstrap_brokers.py
│ │ │ │ ├── get_cluster_policy.py
│ │ │ │ ├── get_compatible_kafka_versions.py
│ │ │ │ ├── list_client_vpc_connections.py
│ │ │ │ ├── list_cluster_operations.py
│ │ │ │ ├── list_nodes.py
│ │ │ │ └── list_scram_secrets.py
│ │ │ ├── read_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_configuration_revision.py
│ │ │ │ ├── describe_configuration.py
│ │ │ │ ├── list_configuration_revisions.py
│ │ │ │ └── list_tags_for_resource.py
│ │ │ ├── read_global
│ │ │ │ ├── __init__.py
│ │ │ │ ├── list_clusters.py
│ │ │ │ ├── list_configurations.py
│ │ │ │ ├── list_kafka_versions.py
│ │ │ │ └── list_vpc_connections.py
│ │ │ ├── read_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ └── describe_vpc_connection.py
│ │ │ └── static_tools
│ │ │ ├── __init__.py
│ │ │ └── cluster_best_practices.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_client_manager.py
│ │ │ ├── test_cluster_metrics_tools.py
│ │ │ ├── test_common_functions.py
│ │ │ ├── test_create_cluster_v2.py
│ │ │ ├── test_create_configuration.py
│ │ │ ├── test_create_vpc_connection.py
│ │ │ ├── test_delete_vpc_connection.py
│ │ │ ├── test_describe_cluster_operation.py
│ │ │ ├── test_describe_cluster.py
│ │ │ ├── test_describe_configuration_revision.py
│ │ │ ├── test_describe_configuration.py
│ │ │ ├── test_describe_vpc_connection.py
│ │ │ ├── test_get_bootstrap_brokers.py
│ │ │ ├── test_get_cluster_policy.py
│ │ │ ├── test_get_compatible_kafka_versions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_list_client_vpc_connections.py
│ │ │ ├── test_list_cluster_operations.py
│ │ │ ├── test_list_clusters.py
│ │ │ ├── test_list_configuration_revisions.py
│ │ │ ├── test_list_configurations.py
│ │ │ ├── test_list_customer_iam_access.py
│ │ │ ├── test_list_kafka_versions.py
│ │ │ ├── test_list_nodes.py
│ │ │ ├── test_list_scram_secrets.py
│ │ │ ├── test_list_tags_for_resource.py
│ │ │ ├── test_list_vpc_connections.py
│ │ │ ├── test_logs_and_telemetry.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mutate_cluster_init.py
│ │ │ ├── test_mutate_cluster_success_cases.py
│ │ │ ├── test_mutate_cluster.py
│ │ │ ├── test_mutate_config_init.py
│ │ │ ├── test_mutate_vpc_init.py
│ │ │ ├── test_read_cluster_init_updated.py
│ │ │ ├── test_read_cluster_init.py
│ │ │ ├── test_read_config_init.py
│ │ │ ├── test_read_global_init.py
│ │ │ ├── test_read_vpc_init.py
│ │ │ ├── test_reject_client_vpc_connection.py
│ │ │ ├── test_server.py
│ │ │ ├── test_static_tools_init.py
│ │ │ ├── test_tag_resource.py
│ │ │ ├── test_tool_descriptions.py
│ │ │ ├── test_untag_resource.py
│ │ │ └── test_update_configuration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-pricing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_pricing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cdk_analyzer.py
│ │ │ ├── consts.py
│ │ │ ├── helpers.py
│ │ │ ├── models.py
│ │ │ ├── pricing_client.py
│ │ │ ├── pricing_transformer.py
│ │ │ ├── report_generator.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ ├── __init__.py
│ │ │ │ ├── COST_REPORT_TEMPLATE.md
│ │ │ │ └── patterns
│ │ │ │ ├── __init__.py
│ │ │ │ └── BEDROCK.md
│ │ │ └── terraform_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cdk_analyzer.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_pricing_client.py
│ │ │ ├── test_pricing_transformer.py
│ │ │ ├── test_report_generator.py
│ │ │ ├── test_server.py
│ │ │ └── test_terraform_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-serverless-mcp-server
│ │ ├── .pre-commit.config.yaml
│ │ ├── .python-version
│ │ ├── .secrets.baseline
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_serverless_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deployment_details.py
│ │ │ │ ├── deployment_list.py
│ │ │ │ ├── template_details.py
│ │ │ │ └── template_list.py
│ │ │ ├── server.py
│ │ │ ├── template
│ │ │ │ ├── __init__.py
│ │ │ │ ├── registry.py
│ │ │ │ ├── renderer.py
│ │ │ │ └── templates
│ │ │ │ ├── backend.j2
│ │ │ │ ├── frontend.j2
│ │ │ │ ├── fullstack.j2
│ │ │ │ └── README.md
│ │ │ ├── templates
│ │ │ │ ├── __init__.py
│ │ │ │ └── iam_policies.py
│ │ │ ├── tools
│ │ │ │ ├── common
│ │ │ │ │ └── base_tool.py
│ │ │ │ ├── esm
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── esm_diagnosis.py
│ │ │ │ │ ├── esm_guidance.py
│ │ │ │ │ ├── esm_recommend.py
│ │ │ │ │ └── secure_esm_guidance.py
│ │ │ │ ├── guidance
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── deploy_serverless_app_help.py
│ │ │ │ │ ├── get_iac_guidance.py
│ │ │ │ │ ├── get_lambda_event_schemas.py
│ │ │ │ │ ├── get_lambda_guidance.py
│ │ │ │ │ └── get_serverless_templates.py
│ │ │ │ ├── poller
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── esm_diagnosis.py
│ │ │ │ │ ├── esm_guidance.py
│ │ │ │ │ └── esm_recommend.py
│ │ │ │ ├── sam
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── sam_build.py
│ │ │ │ │ ├── sam_deploy.py
│ │ │ │ │ ├── sam_init.py
│ │ │ │ │ ├── sam_local_invoke.py
│ │ │ │ │ └── sam_logs.py
│ │ │ │ ├── schemas
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── describe_schema.py
│ │ │ │ │ ├── list_registries.py
│ │ │ │ │ └── search_schema.py
│ │ │ │ └── webapps
│ │ │ │ ├── __init__.py
│ │ │ │ ├── configure_domain.py
│ │ │ │ ├── deploy_webapp.py
│ │ │ │ ├── get_metrics.py
│ │ │ │ ├── update_webapp_frontend.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── deploy_service.py
│ │ │ │ │ ├── frontend_uploader.py
│ │ │ │ │ └── startup_script_generator.py
│ │ │ │ └── webapp_deployment_help.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_client_helper.py
│ │ │ ├── cloudformation.py
│ │ │ ├── const.py
│ │ │ ├── data_scrubber.py
│ │ │ ├── deployment_manager.py
│ │ │ ├── github.py
│ │ │ └── process.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_cloudformation.py
│ │ │ ├── test_configure_domain.py
│ │ │ ├── test_data_scrubber.py
│ │ │ ├── test_deploy_serverless_app_help.py
│ │ │ ├── test_deploy_service.py
│ │ │ ├── test_deploy_webapp.py
│ │ │ ├── test_deployment_details.py
│ │ │ ├── test_deployment_help.py
│ │ │ ├── test_deployment_list.py
│ │ │ ├── test_deployment_manager.py
│ │ │ ├── test_esm_diagnosis.py
│ │ │ ├── test_esm_guidance.py
│ │ │ ├── test_esm_recommend.py
│ │ │ ├── test_frontend_uploader.py
│ │ │ ├── test_get_iac_guidance.py
│ │ │ ├── test_get_lambda_event_schemas.py
│ │ │ ├── test_get_lambda_guidance.py
│ │ │ ├── test_get_metrics.py
│ │ │ ├── test_get_serverless_templates.py
│ │ │ ├── test_github.py
│ │ │ ├── test_iam_policies.py
│ │ │ ├── test_models.py
│ │ │ ├── test_process.py
│ │ │ ├── test_sam_build.py
│ │ │ ├── test_sam_deploy.py
│ │ │ ├── test_sam_init.py
│ │ │ ├── test_sam_local_invoke.py
│ │ │ ├── test_sam_logs.py
│ │ │ ├── test_schemas.py
│ │ │ ├── test_secure_esm_guidance.py
│ │ │ ├── test_server.py
│ │ │ ├── test_startup_script_generator.py
│ │ │ ├── test_template_details.py
│ │ │ ├── test_template_list.py
│ │ │ ├── test_template_registry.py
│ │ │ ├── test_template_renderer.py
│ │ │ └── test_update_webapp_frontend.py
│ │ └── uv.lock
│ ├── aws-support-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_support_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── consts.py
│ │ │ ├── debug_helper.py
│ │ │ ├── errors.py
│ │ │ ├── formatters.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftests.py
│ │ │ ├── test_aws_support_mcp_server.py
│ │ │ └── test_models.py
│ │ └── uv.lock
│ ├── bedrock-kb-retrieval-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── bedrock_kb_retrieval_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── knowledgebases
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clients.py
│ │ │ │ ├── discovery.py
│ │ │ │ └── retrieval.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_clients.py
│ │ │ ├── test_discovery.py
│ │ │ ├── test_env_config.py
│ │ │ ├── test_models.py
│ │ │ ├── test_retrieval.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── billing-cost-management-mcp-server
│ │ ├── __init__.py
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── billing_cost_management_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── decorator.py
│ │ │ │ ├── graviton_migration.py
│ │ │ │ ├── README.md
│ │ │ │ ├── savings_plans.py
│ │ │ │ └── types.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ └── recommendation_templates
│ │ │ │ ├── ebs_volume.template
│ │ │ │ ├── ec2_asg.template
│ │ │ │ ├── ec2_instance.template
│ │ │ │ ├── ecs_service.template
│ │ │ │ ├── idle.template
│ │ │ │ ├── lambda_function.template
│ │ │ │ ├── rds_database.template
│ │ │ │ ├── reserved_instances.template
│ │ │ │ └── savings_plans.template
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_pricing_operations.py
│ │ │ │ ├── aws_pricing_tools.py
│ │ │ │ ├── bcm_pricing_calculator_tools.py
│ │ │ │ ├── budget_tools.py
│ │ │ │ ├── compute_optimizer_tools.py
│ │ │ │ ├── cost_anomaly_tools.py
│ │ │ │ ├── cost_comparison_tools.py
│ │ │ │ ├── cost_explorer_operations.py
│ │ │ │ ├── cost_explorer_tools.py
│ │ │ │ ├── cost_optimization_hub_helpers.py
│ │ │ │ ├── cost_optimization_hub_tools.py
│ │ │ │ ├── free_tier_usage_tools.py
│ │ │ │ ├── recommendation_details_tools.py
│ │ │ │ ├── ri_performance_tools.py
│ │ │ │ ├── sp_performance_tools.py
│ │ │ │ ├── storage_lens_tools.py
│ │ │ │ └── unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_base.py
│ │ │ ├── constants.py
│ │ │ ├── logging_utils.py
│ │ │ └── sql_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── requirements.txt
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_prompts.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── fixtures.py
│ │ │ │ ├── test_aws_bcm_pricing_calculator_tools.py
│ │ │ │ ├── test_aws_pricing_tools.py
│ │ │ │ ├── test_budget_tools.py
│ │ │ │ ├── test_compute_optimizer_tools.py
│ │ │ │ ├── test_cost_anomaly_tools_enhanced.py
│ │ │ │ ├── test_cost_anomaly_tools.py
│ │ │ │ ├── test_cost_comparison_tools.py
│ │ │ │ ├── test_cost_explorer_operations.py
│ │ │ │ ├── test_cost_explorer_tools.py
│ │ │ │ ├── test_cost_optimization_hub_helpers.py
│ │ │ │ ├── test_cost_optimization_hub_tools.py
│ │ │ │ ├── test_free_tier_usage_tools_new.py
│ │ │ │ ├── test_recommendation_details_tools.py
│ │ │ │ ├── test_ri_performance_tools.py
│ │ │ │ ├── test_sp_performance_tools.py
│ │ │ │ ├── test_storage_lens_tools.py
│ │ │ │ └── test_unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── test_aws_service_base.py
│ │ │ └── test_sql_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ccapi-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ccapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── impl
│ │ │ │ ├── __init__.py
│ │ │ │ ├── tools
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── explanation.py
│ │ │ │ │ ├── infrastructure_generation.py
│ │ │ │ │ ├── resource_operations.py
│ │ │ │ │ ├── security_scanning.py
│ │ │ │ │ └── session_management.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ └── validation.py
│ │ │ ├── infrastructure_generator.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── schema_manager.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ └── __init__.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_checkov_install.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_explanation.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_infrastructure_generation.py
│ │ │ ├── test_infrastructure_generator.py
│ │ │ ├── test_models.py
│ │ │ ├── test_resource_operations.py
│ │ │ ├── test_schema_manager.py
│ │ │ ├── test_security_scanning.py
│ │ │ ├── test_server.py
│ │ │ ├── test_session_management.py
│ │ │ └── test_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cdk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cdk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── resources.py
│ │ │ │ ├── search_utils.py
│ │ │ │ ├── server.py
│ │ │ │ └── tools.py
│ │ │ ├── data
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cdk_nag_parser.py
│ │ │ │ ├── construct_descriptions.py
│ │ │ │ ├── genai_cdk_loader.py
│ │ │ │ ├── lambda_layer_parser.py
│ │ │ │ ├── lambda_powertools_loader.py
│ │ │ │ ├── schema_generator.py
│ │ │ │ └── solutions_constructs_parser.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── CDK_GENERAL_GUIDANCE.md
│ │ │ ├── CDK_NAG_GUIDANCE.md
│ │ │ └── lambda_powertools
│ │ │ ├── bedrock.md
│ │ │ ├── cdk.md
│ │ │ ├── dependencies.md
│ │ │ ├── index.md
│ │ │ ├── insights.md
│ │ │ ├── logging.md
│ │ │ ├── metrics.md
│ │ │ └── tracing.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── test_resources_enhanced.py
│ │ │ │ ├── test_resources.py
│ │ │ │ ├── test_search_utils.py
│ │ │ │ ├── test_server.py
│ │ │ │ └── test_tools.py
│ │ │ └── data
│ │ │ ├── test_cdk_nag_parser.py
│ │ │ ├── test_genai_cdk_loader.py
│ │ │ ├── test_lambda_powertools_loader.py
│ │ │ ├── test_schema_generator.py
│ │ │ └── test_solutions_constructs_parser.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cfn-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cfn_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── schema_manager.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_schema_manager.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudtrail-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudtrail_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── tools.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-applicationsignals-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_applicationsignals_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── audit_presentation_utils.py
│ │ │ ├── audit_utils.py
│ │ │ ├── aws_clients.py
│ │ │ ├── canary_utils.py
│ │ │ ├── enablement_guides
│ │ │ │ └── templates
│ │ │ │ └── ec2
│ │ │ │ └── ec2-python-enablement.md
│ │ │ ├── enablement_tools.py
│ │ │ ├── server.py
│ │ │ ├── service_audit_utils.py
│ │ │ ├── service_tools.py
│ │ │ ├── sli_report_client.py
│ │ │ ├── slo_tools.py
│ │ │ ├── trace_tools.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── evals
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── captor.py
│ │ │ │ ├── conversation_runner.py
│ │ │ │ ├── eval_config.py
│ │ │ │ ├── eval_mcp_server_wrapper.py
│ │ │ │ ├── eval_runner.py
│ │ │ │ ├── file_tools.py
│ │ │ │ ├── llm_provider.py
│ │ │ │ ├── mcp_client.py
│ │ │ │ ├── mcp_dependency_mocking_handler.py
│ │ │ │ ├── metrics_tracker.py
│ │ │ │ ├── mock_config_path_normalizer.py
│ │ │ │ ├── process_executor.py
│ │ │ │ ├── task_result.py
│ │ │ │ ├── task.py
│ │ │ │ ├── validation_prompts.py
│ │ │ │ └── validator.py
│ │ │ ├── README.md
│ │ │ ├── requirements.txt
│ │ │ └── tasks
│ │ │ ├── __init__.py
│ │ │ └── applicationsignals
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── get_enablement_guide
│ │ │ │ ├── __init__.py
│ │ │ │ └── enablement_tasks.py
│ │ │ └── investigations
│ │ │ ├── __init__.py
│ │ │ ├── fixtures
│ │ │ │ ├── bug-4-list-audit-findings-all-services-all-auditors.json
│ │ │ │ ├── bug-4-list-audit-findings-all-services-default-auditors.json
│ │ │ │ ├── bug-4-list-audit-findings-document-service-and-all-auditors.json
│ │ │ │ └── bug-4-list-services.json
│ │ │ └── investigation_tasks.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_audit_presentation_utils.py
│ │ │ ├── test_audit_utils.py
│ │ │ ├── test_aws_profile.py
│ │ │ ├── test_canary_utils.py
│ │ │ ├── test_enablement_tools.py
│ │ │ ├── test_initialization.py
│ │ │ ├── test_server_audit_functions.py
│ │ │ ├── test_server_audit_tools.py
│ │ │ ├── test_server.py
│ │ │ ├── test_service_audit_utils.py
│ │ │ ├── test_service_tools_operations.py
│ │ │ ├── test_sli_report_client.py
│ │ │ ├── test_slo_tools.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-appsignals-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_appsignals_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── audit_presentation_utils.py
│ │ │ ├── audit_utils.py
│ │ │ ├── aws_clients.py
│ │ │ ├── canary_utils.py
│ │ │ ├── enablement_guides
│ │ │ │ └── templates
│ │ │ │ └── ec2
│ │ │ │ └── ec2-python-enablement.md
│ │ │ ├── enablement_tools.py
│ │ │ ├── server.py
│ │ │ ├── service_audit_utils.py
│ │ │ ├── service_tools.py
│ │ │ ├── sli_report_client.py
│ │ │ ├── slo_tools.py
│ │ │ ├── trace_tools.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_audit_presentation_utils.py
│ │ │ ├── test_audit_utils.py
│ │ │ ├── test_aws_profile.py
│ │ │ ├── test_canary_utils.py
│ │ │ ├── test_enablement_tools.py
│ │ │ ├── test_initialization.py
│ │ │ ├── test_server_audit_functions.py
│ │ │ ├── test_server_audit_tools.py
│ │ │ ├── test_server.py
│ │ │ ├── test_service_audit_utils.py
│ │ │ ├── test_service_tools_operations.py
│ │ │ ├── test_sli_report_client.py
│ │ │ ├── test_slo_tools.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── cloudformation_template_generator.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── data
│ │ │ │ │ └── metric_metadata.json
│ │ │ │ ├── metric_analyzer.py
│ │ │ │ ├── metric_data_decomposer.py
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── common.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── test_active_alarms.py
│ │ │ │ ├── test_alarm_history_integration.py
│ │ │ │ ├── test_alarm_history.py
│ │ │ │ └── test_alarms_error_handling.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── test_logs_error_handling.py
│ │ │ │ ├── test_logs_models.py
│ │ │ │ └── test_logs_server.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── test_analyze_metric.py
│ │ │ │ ├── test_cloudformation_template_generator.py
│ │ │ │ ├── test_decomposer_trend.py
│ │ │ │ ├── test_metric_analyzer.py
│ │ │ │ ├── test_metrics_error_handling.py
│ │ │ │ ├── test_metrics_models.py
│ │ │ │ ├── test_metrics_server.py
│ │ │ │ ├── test_seasonal_detector.py
│ │ │ │ ├── test_seasonality_enum.py
│ │ │ │ ├── test_utils.py
│ │ │ │ └── test_validation_error.py
│ │ │ ├── test_common_and_server.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── code-doc-gen-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── code_doc_gen_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── doc_generator.py
│ │ │ ├── models.py
│ │ │ ├── repomix_manager.py
│ │ │ └── templates.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_doc_generator_edge_cases.py
│ │ │ ├── test_doc_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_repomix_manager_scenarios.py
│ │ │ ├── test_repomix_manager.py
│ │ │ ├── test_repomix_statistics.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server.py
│ │ │ └── test_templates.py
│ │ └── uv.lock
│ ├── core-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── core_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ └── PROMPT_UNDERSTANDING.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_response_types.py
│ │ │ ├── test_server.py
│ │ │ └── test_static.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cost-explorer-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cost_explorer_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── comparison_handler.py
│ │ │ ├── constants.py
│ │ │ ├── cost_usage_handler.py
│ │ │ ├── forecasting_handler.py
│ │ │ ├── helpers.py
│ │ │ ├── metadata_handler.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utility_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_comparison_handler.py
│ │ │ ├── test_cost_usage_handler.py
│ │ │ ├── test_forecasting_handler.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_metadata_handler.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_utility_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── document-loader-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ ├── document_loader_mcp_server
│ │ │ │ ├── __init__.py
│ │ │ │ └── server.py
│ │ │ └── py.typed
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_document_parsing.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── documentdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── documentdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── analytic_tools.py
│ │ │ ├── config.py
│ │ │ ├── connection_tools.py
│ │ │ ├── db_management_tools.py
│ │ │ ├── query_tools.py
│ │ │ ├── server.py
│ │ │ └── write_tools.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_analytic_tools.py
│ │ │ ├── test_connection_tools.py
│ │ │ ├── test_db_management_tools.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_tools.py
│ │ │ └── test_write_tools.py
│ │ └── uv.lock
│ ├── dynamodb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── dynamodb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── database_analysis_queries.py
│ │ │ ├── database_analyzers.py
│ │ │ ├── markdown_formatter.py
│ │ │ ├── prompts
│ │ │ │ └── dynamodb_architect.md
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── evals
│ │ │ │ ├── dynamic_evaluators.py
│ │ │ │ ├── evaluation_registry.py
│ │ │ │ ├── logging_config.py
│ │ │ │ ├── multiturn_evaluator.py
│ │ │ │ ├── README.md
│ │ │ │ ├── scenarios.py
│ │ │ │ └── test_dspy_evals.py
│ │ │ ├── test_dynamodb_server.py
│ │ │ ├── test_markdown_formatter.py
│ │ │ └── test_source_db_integration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ecs-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ecs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── ecs_troubleshooting.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ ├── status.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── detect_image_pull_failures.py
│ │ │ │ ├── fetch_cloudformation_status.py
│ │ │ │ ├── fetch_network_configuration.py
│ │ │ │ ├── fetch_service_events.py
│ │ │ │ ├── fetch_task_failures.py
│ │ │ │ ├── fetch_task_logs.py
│ │ │ │ ├── get_ecs_troubleshooting_guidance.py
│ │ │ │ └── utils.py
│ │ │ ├── main.py
│ │ │ ├── modules
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_knowledge_proxy.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── deployment_status.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ └── troubleshooting.py
│ │ │ ├── templates
│ │ │ │ ├── ecr_infrastructure.json
│ │ │ │ └── ecs_infrastructure.json
│ │ │ └── utils
│ │ │ ├── arn_parser.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── docker.py
│ │ │ ├── security.py
│ │ │ ├── templates.py
│ │ │ └── time_utils.py
│ │ ├── DEVELOPMENT.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── integ
│ │ │ │ └── mcp-inspector
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── run-tests.sh
│ │ │ │ └── scenarios
│ │ │ │ ├── 01_comprehensive_troubleshooting
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_cleanup.sh
│ │ │ │ │ ├── description.txt
│ │ │ │ │ └── utils
│ │ │ │ │ ├── mcp_helpers.sh
│ │ │ │ │ └── validation_helpers.sh
│ │ │ │ └── 02_test_knowledge_proxy_tools
│ │ │ │ ├── 01_create.sh
│ │ │ │ ├── 02_validate.sh
│ │ │ │ ├── 03_cleanup.sh
│ │ │ │ ├── description.txt
│ │ │ │ └── utils
│ │ │ │ ├── knowledge_validation_helpers.sh
│ │ │ │ └── mcp_knowledge_helpers.sh
│ │ │ ├── llm_testing
│ │ │ │ ├── invalid_cfn_template.yaml
│ │ │ │ ├── README.md
│ │ │ │ ├── run_tests.sh
│ │ │ │ ├── scenarios
│ │ │ │ │ ├── 01_cloudformation_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 02_service_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 03_task_exit_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 04_network_configuration_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 05_resource_constraint_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ └── 06_load_balancer_failure
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ └── description.txt
│ │ │ │ ├── SCRIPT_IMPROVEMENTS.md
│ │ │ │ └── utils
│ │ │ │ ├── aws_helpers.sh
│ │ │ │ └── evaluation_template.md
│ │ │ └── unit
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_delete_api.py
│ │ │ │ ├── test_ecs_troubleshooting.py
│ │ │ │ ├── test_resource_management_api.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ └── test_fetch_network_configuration.py
│ │ │ ├── conftest.py
│ │ │ ├── modules
│ │ │ │ ├── test_aws_knowledge_proxy.py
│ │ │ │ └── test_resource_management_module.py
│ │ │ ├── test_aws_role_utils.py
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_containerize.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_docker_utils.py
│ │ │ ├── test_docker_with_role.py
│ │ │ ├── test_image_pull_failure_extended.py
│ │ │ ├── test_image_pull_failure.py
│ │ │ ├── test_infrastructure_role.py
│ │ │ ├── test_infrastructure.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_main.py
│ │ │ ├── test_resource_management_api_operation.py
│ │ │ ├── test_resource_management_tool.py
│ │ │ ├── test_resource_management.py
│ │ │ ├── test_security_integration.py
│ │ │ ├── test_status_pytest.py
│ │ │ ├── test_status.py
│ │ │ ├── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_detect_image_pull_failures.py
│ │ │ │ ├── test_fetch_cloudformation_status.py
│ │ │ │ ├── test_fetch_service_events.py
│ │ │ │ ├── test_fetch_task_failures.py
│ │ │ │ ├── test_fetch_task_logs.py
│ │ │ │ ├── test_get_ecs_troubleshooting_guidance.py
│ │ │ │ ├── test_is_ecr_image_security.py
│ │ │ │ └── test_utils.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── async_test_utils.py
│ │ │ ├── test_arn_parser.py
│ │ │ ├── test_config.py
│ │ │ ├── test_docker.py
│ │ │ ├── test_response_sanitization.py
│ │ │ ├── test_security_extended.py
│ │ │ ├── test_security.py
│ │ │ ├── test_templates.py
│ │ │ └── test_time_utils.py
│ │ └── uv.lock
│ ├── eks-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── eks_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── cloudwatch_handler.py
│ │ │ ├── cloudwatch_metrics_guidance_handler.py
│ │ │ ├── consts.py
│ │ │ ├── data
│ │ │ │ └── eks_cloudwatch_metrics_guidance.json
│ │ │ ├── eks_kb_handler.py
│ │ │ ├── eks_stack_handler.py
│ │ │ ├── iam_handler.py
│ │ │ ├── insights_handler.py
│ │ │ ├── k8s_apis.py
│ │ │ ├── k8s_client_cache.py
│ │ │ ├── k8s_handler.py
│ │ │ ├── logging_helper.py
│ │ │ ├── models.py
│ │ │ ├── scripts
│ │ │ │ └── update_eks_cloudwatch_metrics_guidance.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ ├── eks-templates
│ │ │ │ │ └── eks-with-vpc.yaml
│ │ │ │ └── k8s-templates
│ │ │ │ ├── deployment.yaml
│ │ │ │ └── service.yaml
│ │ │ └── vpc_config_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_cloudwatch_handler.py
│ │ │ ├── test_cloudwatch_metrics_guidance_handler.py
│ │ │ ├── test_eks_kb_handler.py
│ │ │ ├── test_eks_stack_handler.py
│ │ │ ├── test_iam_handler.py
│ │ │ ├── test_init.py
│ │ │ ├── test_insights_handler.py
│ │ │ ├── test_k8s_apis.py
│ │ │ ├── test_k8s_client_cache.py
│ │ │ ├── test_k8s_handler.py
│ │ │ ├── test_logging_helper.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_vpc_config_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── elasticache-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── elasticache_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── decorators.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ └── processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_log_group.py
│ │ │ │ ├── describe_log_groups.py
│ │ │ │ ├── describe_log_streams.py
│ │ │ │ ├── filter_log_events.py
│ │ │ │ └── get_log_events.py
│ │ │ ├── firehose
│ │ │ │ ├── __init__.py
│ │ │ │ └── list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_apply_update_action.py
│ │ │ │ ├── batch_stop_update_action.py
│ │ │ │ ├── describe_cache_engine_versions.py
│ │ │ │ ├── describe_engine_default_parameters.py
│ │ │ │ ├── describe_events.py
│ │ │ │ └── describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── complete_migration.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ ├── processors.py
│ │ │ │ ├── start_migration.py
│ │ │ │ └── test_migration.py
│ │ │ └── serverless
│ │ │ ├── __init__.py
│ │ │ ├── connect.py
│ │ │ ├── create.py
│ │ │ ├── delete.py
│ │ │ ├── describe.py
│ │ │ ├── models.py
│ │ │ └── modify.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection.py
│ │ │ ├── test_decorators.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── tools
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create_additional.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ └── test_processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ └── test_get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_create_log_group.py
│ │ │ │ ├── test_describe_log_groups.py
│ │ │ │ ├── test_describe_log_streams.py
│ │ │ │ ├── test_filter_log_events.py
│ │ │ │ └── test_get_log_events.py
│ │ │ ├── firehose
│ │ │ │ └── test_list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_batch_apply_update_action.py
│ │ │ │ ├── test_batch_stop_update_action.py
│ │ │ │ ├── test_describe_cache_engine_versions.py
│ │ │ │ ├── test_describe_engine_default_parameters.py
│ │ │ │ ├── test_describe_events.py
│ │ │ │ └── test_describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_complete_migration.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_optional_fields.py
│ │ │ │ ├── test_connect_partial_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ ├── test_processors.py
│ │ │ │ ├── test_start_migration.py
│ │ │ │ └── test_test_migration.py
│ │ │ └── serverless
│ │ │ ├── test_connect_additional.py
│ │ │ ├── test_connect_coverage_additional.py
│ │ │ ├── test_connect_optional_fields.py
│ │ │ ├── test_connect.py
│ │ │ ├── test_create.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_describe.py
│ │ │ └── test_modify.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── finch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── finch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── build.py
│ │ │ ├── common.py
│ │ │ ├── ecr.py
│ │ │ ├── push.py
│ │ │ └── vm.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_cli_flags.py
│ │ │ ├── test_logging_configuration.py
│ │ │ ├── test_server.py
│ │ │ ├── test_utils_build.py
│ │ │ ├── test_utils_common.py
│ │ │ ├── test_utils_ecr.py
│ │ │ ├── test_utils_push.py
│ │ │ └── test_utils_vm.py
│ │ └── uv.lock
│ ├── frontend-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── frontend_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ └── react
│ │ │ │ ├── essential-knowledge.md
│ │ │ │ └── troubleshooting.md
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ └── file_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_file_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── git-repo-research-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── git_repo_research_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── defaults.py
│ │ │ ├── embeddings.py
│ │ │ ├── github_search.py
│ │ │ ├── indexer.py
│ │ │ ├── models.py
│ │ │ ├── repository.py
│ │ │ ├── search.py
│ │ │ ├── server.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_errors_repository.py
│ │ │ ├── test_github_search_edge_cases.py
│ │ │ ├── test_graphql_github_search.py
│ │ │ ├── test_local_repository.py
│ │ │ ├── test_repository_utils.py
│ │ │ ├── test_rest_github_search.py
│ │ │ ├── test_search.py
│ │ │ ├── test_server.py
│ │ │ └── test_url_repository.py
│ │ └── uv.lock
│ ├── healthlake-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── healthlake_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── fhir_operations.py
│ │ │ ├── main.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── mcp_config.json
│ │ │ └── README.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_fhir_client_comprehensive.py
│ │ │ ├── test_fhir_error_scenarios.py
│ │ │ ├── test_fhir_operations.py
│ │ │ ├── test_integration_mock_based.py
│ │ │ ├── test_main_edge_cases.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mcp_integration_coverage.py
│ │ │ ├── test_models_edge_cases.py
│ │ │ ├── test_models.py
│ │ │ ├── test_readonly_mode.py
│ │ │ ├── test_server_core.py
│ │ │ ├── test_server_error_handling.py
│ │ │ ├── test_server_mcp_handlers.py
│ │ │ ├── test_server_toolhandler.py
│ │ │ └── test_server_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── iam-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── iam_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── DESIGN_COMPLIANCE.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── get_policy_document_example.py
│ │ │ └── inline_policy_demo.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_inline_policies.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── lambda-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── lambda_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── README.md
│ │ │ └── sample_functions
│ │ │ ├── customer-create
│ │ │ │ └── app.py
│ │ │ ├── customer-id-from-email
│ │ │ │ └── app.py
│ │ │ ├── customer-info-from-id
│ │ │ │ └── app.py
│ │ │ └── template.yml
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_format_lambda_response.py
│ │ │ ├── test_integration_coverage.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_register_lambda_functions.py
│ │ │ ├── test_schema_integration.py
│ │ │ ├── test_server_coverage_additional.py
│ │ │ ├── test_server_coverage.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mcp-lambda-handler
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── mcp_lambda_handler
│ │ │ ├── __init__.py
│ │ │ ├── mcp_lambda_handler.py
│ │ │ ├── session.py
│ │ │ └── types.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_lambda_handler.py
│ │ └── uv.lock
│ ├── memcached-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── memcached_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ └── cache.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_cache_readonly.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mysql-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── mysql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── connection
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abstract_db_connection.py
│ │ │ │ ├── asyncmy_pool_connection.py
│ │ │ │ ├── db_connection_singleton.py
│ │ │ │ └── rds_data_api_connection.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_abstract_db_connection.py
│ │ │ ├── test_asyncmy_pool_connection.py
│ │ │ ├── test_db_connection_singleton.py
│ │ │ ├── test_rds_data_api_connection.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── nova-canvas-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── nova_canvas_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── novacanvas.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_novacanvas.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── openapi-mcp-server
│ │ ├── .coveragerc
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── AUTHENTICATION.md
│ │ ├── AWS_BEST_PRACTICES.md
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── openapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ └── config.py
│ │ │ ├── auth
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_key_auth.py
│ │ │ │ ├── auth_cache.py
│ │ │ │ ├── auth_errors.py
│ │ │ │ ├── auth_factory.py
│ │ │ │ ├── auth_protocol.py
│ │ │ │ ├── auth_provider.py
│ │ │ │ ├── base_auth.py
│ │ │ │ ├── basic_auth.py
│ │ │ │ ├── bearer_auth.py
│ │ │ │ ├── cognito_auth.py
│ │ │ │ └── register.py
│ │ │ ├── patch
│ │ │ │ └── __init__.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── generators
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── operation_prompts.py
│ │ │ │ │ └── workflow_prompts.py
│ │ │ │ ├── models.py
│ │ │ │ └── prompt_manager.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache_provider.py
│ │ │ ├── config.py
│ │ │ ├── error_handler.py
│ │ │ ├── http_client.py
│ │ │ ├── metrics_provider.py
│ │ │ ├── openapi_validator.py
│ │ │ └── openapi.py
│ │ ├── CHANGELOG.md
│ │ ├── DEPLOYMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── OBSERVABILITY.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── api
│ │ │ │ └── test_config.py
│ │ │ ├── auth
│ │ │ │ ├── test_api_key_auth.py
│ │ │ │ ├── test_auth_cache.py
│ │ │ │ ├── test_auth_errors.py
│ │ │ │ ├── test_auth_factory_caching.py
│ │ │ │ ├── test_auth_factory_coverage.py
│ │ │ │ ├── test_auth_factory.py
│ │ │ │ ├── test_auth_protocol_additional.py
│ │ │ │ ├── test_auth_protocol_boost.py
│ │ │ │ ├── test_auth_protocol_coverage.py
│ │ │ │ ├── test_auth_protocol_extended.py
│ │ │ │ ├── test_auth_protocol_improved.py
│ │ │ │ ├── test_auth_protocol.py
│ │ │ │ ├── test_auth_provider_additional.py
│ │ │ │ ├── test_base_auth_coverage.py
│ │ │ │ ├── test_base_auth.py
│ │ │ │ ├── test_basic_auth.py
│ │ │ │ ├── test_bearer_auth.py
│ │ │ │ ├── test_cognito_auth_additional_coverage.py
│ │ │ │ ├── test_cognito_auth_boost_coverage.py
│ │ │ │ ├── test_cognito_auth_client_credentials.py
│ │ │ │ ├── test_cognito_auth_coverage_boost.py
│ │ │ │ ├── test_cognito_auth_exceptions.py
│ │ │ │ ├── test_cognito_auth.py
│ │ │ │ ├── test_register_coverage.py
│ │ │ │ └── test_register.py
│ │ │ ├── prompts
│ │ │ │ ├── standalone
│ │ │ │ │ ├── test_operation_prompt.py
│ │ │ │ │ ├── test_prompt_arguments.py
│ │ │ │ │ └── test_secure_operation_prompt.py
│ │ │ │ ├── test_mcp_prompt_manager_integration.py
│ │ │ │ ├── test_mcp_prompt_manager.py
│ │ │ │ ├── test_models_dict_method.py
│ │ │ │ ├── test_operation_prompts_extended.py
│ │ │ │ ├── test_prompt_manager_additional.py
│ │ │ │ ├── test_prompt_manager_comprehensive.py
│ │ │ │ ├── test_prompt_manager_coverage.py
│ │ │ │ └── test_prompt_registration.py
│ │ │ ├── README.md
│ │ │ ├── test_api_name.py
│ │ │ ├── test_cache_coverage_89.py
│ │ │ ├── test_client.py
│ │ │ ├── test_coverage_boost.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main_extended.py
│ │ │ ├── test_main.py
│ │ │ ├── test_openapi_coverage_89.py
│ │ │ ├── test_server_auth_errors.py
│ │ │ ├── test_server_coverage_boost_2.py
│ │ │ ├── test_server_coverage_boost.py
│ │ │ ├── test_server_exception_handling.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server_httpx_version.py
│ │ │ ├── test_server_part1.py
│ │ │ ├── test_server_route_logging.py
│ │ │ ├── test_server_signal_handlers.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── test_cache_provider.py
│ │ │ ├── test_error_handler_boost.py
│ │ │ ├── test_error_handler_extended.py
│ │ │ ├── test_error_handler_fix.py
│ │ │ ├── test_error_handler.py
│ │ │ ├── test_http_client_comprehensive.py
│ │ │ ├── test_http_client_extended.py
│ │ │ ├── test_http_client_extended2.py
│ │ │ ├── test_http_client_import_error.py
│ │ │ ├── test_http_client.py
│ │ │ ├── test_metrics_provider_decorators.py
│ │ │ ├── test_metrics_provider_extended2.py
│ │ │ ├── test_metrics_provider_prometheus.py
│ │ │ ├── test_metrics_provider.py
│ │ │ ├── test_openapi_validator.py
│ │ │ └── test_openapi.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── postgres-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── postgres_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── connection
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abstract_db_connection.py
│ │ │ │ ├── db_connection_singleton.py
│ │ │ │ ├── psycopg_pool_connection.py
│ │ │ │ └── rds_api_connection.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_psycopg_connector.py
│ │ │ ├── test_server.py
│ │ │ └── test_singleton.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── prometheus-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── prometheus_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_aws_credentials.py
│ │ │ ├── test_config_manager.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_coverage_gaps.py
│ │ │ ├── test_coverage_improvement.py
│ │ │ ├── test_final_coverage.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_prometheus_client.py
│ │ │ ├── test_prometheus_connection.py
│ │ │ ├── test_security_validator.py
│ │ │ ├── test_server_coverage.py
│ │ │ ├── test_tools.py
│ │ │ └── test_workspace_config.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── redshift-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── redshift_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── redshift.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_redshift.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── s3-tables-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── s3_tables_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── database.py
│ │ │ ├── engines
│ │ │ │ ├── __init__.py
│ │ │ │ └── pyiceberg.py
│ │ │ ├── file_processor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── csv.py
│ │ │ │ ├── parquet.py
│ │ │ │ └── utils.py
│ │ │ ├── models.py
│ │ │ ├── namespaces.py
│ │ │ ├── resources.py
│ │ │ ├── s3_operations.py
│ │ │ ├── server.py
│ │ │ ├── table_buckets.py
│ │ │ ├── tables.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTEXT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_csv.py
│ │ │ ├── test_database.py
│ │ │ ├── test_file_processor_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_namespaces.py
│ │ │ ├── test_parquet.py
│ │ │ ├── test_pyiceberg.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_s3_operations.py
│ │ │ ├── test_server.py
│ │ │ ├── test_table_buckets.py
│ │ │ ├── test_tables.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── stepfunctions-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── stepfunctions_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_create_state_machine_tool.py
│ │ │ ├── test_filter_state_machines_by_tag.py
│ │ │ ├── test_format_state_machine_response.py
│ │ │ ├── test_get_schema_arn_from_state_machine_arn.py
│ │ │ ├── test_get_schema_from_registry.py
│ │ │ ├── test_invoke_express_state_machine_impl.py
│ │ │ ├── test_invoke_standard_state_machine_impl.py
│ │ │ ├── test_main.py
│ │ │ ├── test_register_state_machines.py
│ │ │ ├── test_sanitize_tool_name.py
│ │ │ ├── test_server.py
│ │ │ └── test_validate_state_machine_name.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── syntheticdata-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── syntheticdata_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── pandas_interpreter.py
│ │ │ ├── server.py
│ │ │ └── storage
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── loader.py
│ │ │ └── s3.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_constants.py
│ │ │ ├── test_pandas_interpreter.py
│ │ │ ├── test_server.py
│ │ │ └── test_storage
│ │ │ ├── __init__.py
│ │ │ ├── test_loader.py
│ │ │ └── test_s3.py
│ │ └── uv.lock
│ ├── terraform-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── terraform_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── impl
│ │ │ │ ├── resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── terraform_aws_provider_resources_listing.py
│ │ │ │ │ └── terraform_awscc_provider_resources_listing.py
│ │ │ │ └── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── execute_terraform_command.py
│ │ │ │ ├── execute_terragrunt_command.py
│ │ │ │ ├── run_checkov_scan.py
│ │ │ │ ├── search_aws_provider_docs.py
│ │ │ │ ├── search_awscc_provider_docs.py
│ │ │ │ ├── search_specific_aws_ia_modules.py
│ │ │ │ ├── search_user_provided_module.py
│ │ │ │ └── utils.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── scripts
│ │ │ │ ├── generate_aws_provider_resources.py
│ │ │ │ ├── generate_awscc_provider_resources.py
│ │ │ │ └── scrape_aws_terraform_best_practices.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── AWS_PROVIDER_RESOURCES.md
│ │ │ ├── AWS_TERRAFORM_BEST_PRACTICES.md
│ │ │ ├── AWSCC_PROVIDER_RESOURCES.md
│ │ │ ├── MCP_INSTRUCTIONS.md
│ │ │ └── TERRAFORM_WORKFLOW_GUIDE.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_command_impl.py
│ │ │ ├── test_execute_terraform_command.py
│ │ │ ├── test_execute_terragrunt_command.py
│ │ │ ├── test_models.py
│ │ │ ├── test_parameter_annotations.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_run_checkov_scan.py
│ │ │ ├── test_search_user_provided_module.py
│ │ │ ├── test_server.py
│ │ │ ├── test_tool_implementations.py
│ │ │ ├── test_utils_additional.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── timestream-for-influxdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── timestream_for_influxdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── valkey-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── valkey_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── bitmap.py
│ │ │ │ ├── hash.py
│ │ │ │ ├── hyperloglog.py
│ │ │ │ ├── json.py
│ │ │ │ ├── list.py
│ │ │ │ ├── misc.py
│ │ │ │ ├── server_management.py
│ │ │ │ ├── set.py
│ │ │ │ ├── sorted_set.py
│ │ │ │ ├── stream.py
│ │ │ │ └── string.py
│ │ │ └── version.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_bitmap.py
│ │ │ ├── test_config.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_hash.py
│ │ │ ├── test_hyperloglog.py
│ │ │ ├── test_init.py
│ │ │ ├── test_json_additional.py
│ │ │ ├── test_json_readonly.py
│ │ │ ├── test_json.py
│ │ │ ├── test_list_additional.py
│ │ │ ├── test_list_readonly.py
│ │ │ ├── test_list.py
│ │ │ ├── test_main.py
│ │ │ ├── test_misc.py
│ │ │ ├── test_server_management.py
│ │ │ ├── test_set_readonly.py
│ │ │ ├── test_set.py
│ │ │ ├── test_sorted_set_additional.py
│ │ │ ├── test_sorted_set_readonly.py
│ │ │ ├── test_sorted_set.py
│ │ │ ├── test_stream_additional.py
│ │ │ ├── test_stream_readonly.py
│ │ │ ├── test_stream.py
│ │ │ └── test_string.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ └── well-architected-security-mcp-server
│ ├── .python-version
│ ├── awslabs
│ │ └── well_architected_security_mcp_server
│ │ ├── __init__.py
│ │ ├── consts.py
│ │ ├── server.py
│ │ └── util
│ │ ├── __init__.py
│ │ ├── network_security.py
│ │ ├── prompt_utils.py
│ │ ├── resource_utils.py
│ │ ├── security_services.py
│ │ └── storage_security.py
│ ├── PROMPT_TEMPLATE.md
│ ├── pyproject.toml
│ ├── README.md
│ ├── tests
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── README.md
│ │ ├── test_access_analyzer_fix.py
│ │ ├── test_network_security_additional.py
│ │ ├── test_network_security.py
│ │ ├── test_prompt_utils_coverage.py
│ │ ├── test_prompt_utils.py
│ │ ├── test_resource_utils_fix.py
│ │ ├── test_resource_utils.py
│ │ ├── test_security_services_additional.py
│ │ ├── test_security_services_coverage.py
│ │ ├── test_security_services.py
│ │ ├── test_server_additional.py
│ │ ├── test_server_coverage.py
│ │ ├── test_server_prompts.py
│ │ ├── test_server_security_findings.py
│ │ ├── test_server.py
│ │ ├── test_storage_security_additional.py
│ │ ├── test_storage_security_comprehensive.py
│ │ ├── test_storage_security_edge_cases.py
│ │ ├── test_storage_security_recommendations.py
│ │ ├── test_storage_security.py
│ │ └── test_user_agent_config.py
│ └── uv.lock
├── testing
│ ├── __init__.py
│ ├── mcp_test_client.py
│ ├── mcp_test_runner.py
│ ├── pytest_utils.py
│ ├── README.md
│ └── types.py
└── VIBE_CODING_TIPS_TRICKS.md
```
# Files
--------------------------------------------------------------------------------
/src/aws-healthomics-mcp-server/tests/test_workflow_management.py:
--------------------------------------------------------------------------------
```python
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 |
15 | """Unit tests for workflow management tools."""
16 |
17 | import base64
18 | import botocore.exceptions
19 | import pytest
20 | from awslabs.aws_healthomics_mcp_server.tools.workflow_management import (
21 | create_workflow,
22 | create_workflow_version,
23 | get_workflow,
24 | list_workflow_versions,
25 | list_workflows,
26 | )
27 | from datetime import datetime, timezone
28 | from unittest.mock import AsyncMock, MagicMock, patch
29 |
30 |
31 | @pytest.mark.asyncio
32 | async def test_list_workflows_success():
33 | """Test successful listing of workflows."""
34 | # Mock response data
35 | creation_time = datetime.now(timezone.utc)
36 | mock_response = {
37 | 'items': [
38 | {
39 | 'id': 'wfl-12345',
40 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
41 | 'name': 'test-workflow-1',
42 | 'description': 'Test workflow 1',
43 | 'status': 'ACTIVE',
44 | 'parameters': {'param1': 'value1'},
45 | 'storageType': 'DYNAMIC',
46 | 'type': 'WDL',
47 | 'creationTime': creation_time,
48 | },
49 | {
50 | 'id': 'wfl-67890',
51 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-67890',
52 | 'name': 'test-workflow-2',
53 | 'status': 'ACTIVE',
54 | 'storageType': 'STATIC',
55 | 'storageCapacity': 100,
56 | 'type': 'CWL',
57 | 'creationTime': creation_time,
58 | },
59 | ],
60 | 'nextToken': 'next-page-token',
61 | }
62 |
63 | # Mock context and client
64 | mock_ctx = AsyncMock()
65 | mock_client = MagicMock()
66 | mock_client.list_workflows.return_value = mock_response
67 |
68 | with patch(
69 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
70 | return_value=mock_client,
71 | ):
72 | result = await list_workflows(ctx=mock_ctx, max_results=10, next_token=None)
73 |
74 | # Verify client was called correctly
75 | mock_client.list_workflows.assert_called_once_with(maxResults=10)
76 |
77 | # Verify result structure
78 | assert 'workflows' in result
79 | assert 'nextToken' in result
80 | assert result['nextToken'] == 'next-page-token'
81 | assert len(result['workflows']) == 2
82 |
83 | # Verify first workflow
84 | wf1 = result['workflows'][0]
85 | assert wf1['id'] == 'wfl-12345'
86 | assert wf1['name'] == 'test-workflow-1'
87 | assert wf1['description'] == 'Test workflow 1'
88 | assert wf1['status'] == 'ACTIVE'
89 | assert wf1['parameters'] == {'param1': 'value1'}
90 | assert wf1['storageType'] == 'DYNAMIC'
91 | assert wf1['type'] == 'WDL'
92 | assert wf1['creationTime'] == creation_time.isoformat()
93 |
94 | # Verify second workflow
95 | wf2 = result['workflows'][1]
96 | assert wf2['id'] == 'wfl-67890'
97 | assert wf2['status'] == 'ACTIVE'
98 | assert wf2['storageType'] == 'STATIC'
99 | assert wf2['storageCapacity'] == 100
100 |
101 |
102 | @pytest.mark.asyncio
103 | async def test_list_workflows_empty_response():
104 | """Test listing workflows with empty response."""
105 | mock_response = {'items': []}
106 |
107 | # Mock context and client
108 | mock_ctx = AsyncMock()
109 | mock_client = MagicMock()
110 | mock_client.list_workflows.return_value = mock_response
111 |
112 | with patch(
113 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
114 | return_value=mock_client,
115 | ):
116 | result = await list_workflows(ctx=mock_ctx, max_results=10, next_token=None)
117 |
118 | # Verify empty result
119 | assert result['workflows'] == []
120 | assert 'nextToken' not in result
121 |
122 |
123 | @pytest.mark.asyncio
124 | async def test_list_workflows_with_pagination():
125 | """Test listing workflows with pagination."""
126 | mock_response = {
127 | 'items': [{'id': 'wfl-12345', 'name': 'test-workflow'}],
128 | 'nextToken': 'next-page-token',
129 | }
130 |
131 | # Mock context and client
132 | mock_ctx = AsyncMock()
133 | mock_client = MagicMock()
134 | mock_client.list_workflows.return_value = mock_response
135 |
136 | with patch(
137 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
138 | return_value=mock_client,
139 | ):
140 | result = await list_workflows(ctx=mock_ctx, max_results=10, next_token='current-token')
141 |
142 | # Verify pagination parameters
143 | mock_client.list_workflows.assert_called_once_with(
144 | maxResults=10, startingToken='current-token'
145 | )
146 | assert result['nextToken'] == 'next-page-token'
147 |
148 |
149 | @pytest.mark.asyncio
150 | async def test_list_workflows_boto_error():
151 | """Test handling of BotoCoreError in list_workflows."""
152 | # Mock context and client
153 | mock_ctx = AsyncMock()
154 | mock_client = MagicMock()
155 | mock_client.list_workflows.side_effect = botocore.exceptions.BotoCoreError()
156 |
157 | with patch(
158 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
159 | return_value=mock_client,
160 | ):
161 | with pytest.raises(botocore.exceptions.BotoCoreError):
162 | await list_workflows(ctx=mock_ctx, max_results=10, next_token=None)
163 |
164 | # Verify error was reported to context
165 | mock_ctx.error.assert_called_once()
166 | assert 'AWS error listing workflows' in mock_ctx.error.call_args[0][0]
167 |
168 |
169 | @pytest.mark.asyncio
170 | async def test_list_workflows_unexpected_error():
171 | """Test handling of unexpected errors in list_workflows."""
172 | # Mock context and client
173 | mock_ctx = AsyncMock()
174 | mock_client = MagicMock()
175 | mock_client.list_workflows.side_effect = Exception('Unexpected error')
176 |
177 | with patch(
178 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
179 | return_value=mock_client,
180 | ):
181 | with pytest.raises(Exception, match='Unexpected error'):
182 | await list_workflows(ctx=mock_ctx, max_results=10, next_token=None)
183 |
184 | # Verify error was reported to context
185 | mock_ctx.error.assert_called_once()
186 | assert 'Unexpected error listing workflows' in mock_ctx.error.call_args[0][0]
187 |
188 |
189 | @pytest.mark.asyncio
190 | async def test_get_workflow_success():
191 | """Test successful retrieval of workflow details."""
192 | # Mock response data
193 | creation_time = datetime.now(timezone.utc)
194 | mock_response = {
195 | 'id': 'wfl-12345',
196 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
197 | 'name': 'test-workflow',
198 | 'status': 'ACTIVE',
199 | 'statusMessage': 'Workflow is ready for execution',
200 | 'type': 'WDL',
201 | 'description': 'Test workflow description',
202 | 'parameterTemplate': {'param1': {'type': 'string'}},
203 | 'creationTime': creation_time,
204 | }
205 |
206 | # Mock context and client
207 | mock_ctx = AsyncMock()
208 | mock_client = MagicMock()
209 | mock_client.get_workflow.return_value = mock_response
210 |
211 | with patch(
212 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
213 | return_value=mock_client,
214 | ):
215 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
216 |
217 | # Verify client was called correctly
218 | mock_client.get_workflow.assert_called_once_with(id='wfl-12345')
219 |
220 | # Verify result contains all expected fields
221 | assert result['id'] == 'wfl-12345'
222 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
223 | assert result['name'] == 'test-workflow'
224 | assert result['status'] == 'ACTIVE'
225 | assert result['statusMessage'] == 'Workflow is ready for execution'
226 | assert result['type'] == 'WDL'
227 | assert result['description'] == 'Test workflow description'
228 | assert result['parameterTemplate'] == {'param1': {'type': 'string'}}
229 | assert result['creationTime'] == creation_time.isoformat()
230 |
231 |
232 | @pytest.mark.asyncio
233 | async def test_get_workflow_with_export():
234 | """Test workflow retrieval with export definition."""
235 | # Mock response data with presigned URL (as returned by AWS API)
236 | mock_response = {
237 | 'id': 'wfl-12345',
238 | 'name': 'test-workflow',
239 | 'definition': 'https://s3.amazonaws.com/bucket/workflow-definition.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...',
240 | }
241 |
242 | # Mock context and client
243 | mock_ctx = AsyncMock()
244 | mock_client = MagicMock()
245 | mock_client.get_workflow.return_value = mock_response
246 |
247 | with patch(
248 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
249 | return_value=mock_client,
250 | ):
251 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=True)
252 |
253 | # Verify export parameter was passed
254 | mock_client.get_workflow.assert_called_once_with(id='wfl-12345', export=['DEFINITION'])
255 |
256 | # Verify presigned URL was included in result
257 | assert result['definition'].startswith('https://s3.amazonaws.com/')
258 | assert 'X-Amz-Algorithm' in result['definition']
259 |
260 |
261 | @pytest.mark.asyncio
262 | async def test_get_workflow_without_export():
263 | """Test workflow retrieval without export definition."""
264 | # Mock response data without definition field (normal response)
265 | creation_time = datetime.now(timezone.utc)
266 | mock_response = {
267 | 'id': 'wfl-12345',
268 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
269 | 'name': 'test-workflow',
270 | 'status': 'ACTIVE',
271 | 'type': 'WDL',
272 | 'description': 'Test workflow description',
273 | 'parameterTemplate': {'param1': {'type': 'string'}},
274 | 'creationTime': creation_time,
275 | }
276 |
277 | # Mock context and client
278 | mock_ctx = AsyncMock()
279 | mock_client = MagicMock()
280 | mock_client.get_workflow.return_value = mock_response
281 |
282 | with patch(
283 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
284 | return_value=mock_client,
285 | ):
286 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
287 |
288 | # Verify export parameter was NOT passed
289 | mock_client.get_workflow.assert_called_once_with(id='wfl-12345')
290 |
291 | # Verify no definition field in result
292 | assert 'definition' not in result
293 |
294 | # Verify other fields are present
295 | assert result['parameterTemplate'] == {'param1': {'type': 'string'}}
296 |
297 |
298 | @pytest.mark.asyncio
299 | async def test_get_workflow_minimal_response():
300 | """Test workflow retrieval with minimal response fields."""
301 | # Mock response with minimal fields
302 | creation_time = datetime.now(timezone.utc)
303 | mock_response = {
304 | 'id': 'wfl-12345',
305 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
306 | 'name': 'test-workflow',
307 | 'status': 'ACTIVE',
308 | 'type': 'WDL',
309 | 'creationTime': creation_time,
310 | }
311 |
312 | # Mock context and client
313 | mock_ctx = AsyncMock()
314 | mock_client = MagicMock()
315 | mock_client.get_workflow.return_value = mock_response
316 |
317 | with patch(
318 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
319 | return_value=mock_client,
320 | ):
321 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
322 |
323 | # Verify required fields
324 | assert result['id'] == 'wfl-12345'
325 | assert result['status'] == 'ACTIVE'
326 | assert result['creationTime'] == creation_time.isoformat()
327 |
328 | # Verify optional fields are not present
329 | assert 'description' not in result
330 | assert 'parameterTemplate' not in result
331 | assert 'definition' not in result
332 |
333 |
334 | @pytest.mark.asyncio
335 | async def test_get_workflow_boto_error():
336 | """Test handling of BotoCoreError in get_workflow."""
337 | # Mock context and client
338 | mock_ctx = AsyncMock()
339 | mock_client = MagicMock()
340 | mock_client.get_workflow.side_effect = botocore.exceptions.BotoCoreError()
341 |
342 | with patch(
343 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
344 | return_value=mock_client,
345 | ):
346 | with pytest.raises(botocore.exceptions.BotoCoreError):
347 | await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
348 |
349 | # Verify error was reported to context
350 | mock_ctx.error.assert_called_once()
351 | assert 'AWS error getting workflow' in mock_ctx.error.call_args[0][0]
352 |
353 |
354 | @pytest.mark.asyncio
355 | async def test_get_workflow_unexpected_error():
356 | """Test handling of unexpected errors in get_workflow."""
357 | # Mock context and client
358 | mock_ctx = AsyncMock()
359 | mock_client = MagicMock()
360 | mock_client.get_workflow.side_effect = Exception('Unexpected error')
361 |
362 | with patch(
363 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
364 | return_value=mock_client,
365 | ):
366 | with pytest.raises(Exception, match='Unexpected error'):
367 | await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
368 |
369 | # Verify error was reported to context
370 | mock_ctx.error.assert_called_once()
371 | assert 'Unexpected error getting workflow' in mock_ctx.error.call_args[0][0]
372 |
373 |
374 | @pytest.mark.asyncio
375 | async def test_get_workflow_none_timestamp():
376 | """Test handling of None timestamp in get_workflow."""
377 | # Mock response with None timestamp
378 | mock_response = {
379 | 'id': 'wfl-12345',
380 | 'name': 'test-workflow',
381 | 'status': 'ACTIVE',
382 | 'type': 'WDL',
383 | 'creationTime': None,
384 | }
385 |
386 | # Mock context and client
387 | mock_ctx = AsyncMock()
388 | mock_client = MagicMock()
389 | mock_client.get_workflow.return_value = mock_response
390 |
391 | with patch(
392 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
393 | return_value=mock_client,
394 | ):
395 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
396 |
397 | # Verify timestamp handling
398 | assert result['creationTime'] is None
399 |
400 |
401 | @pytest.mark.asyncio
402 | async def test_get_workflow_with_status_message():
403 | """Test workflow retrieval with status message."""
404 | # Mock response with status message
405 | creation_time = datetime.now(timezone.utc)
406 | mock_response = {
407 | 'id': 'wfl-12345',
408 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
409 | 'name': 'test-workflow',
410 | 'status': 'FAILED',
411 | 'statusMessage': 'Workflow validation failed: Invalid WDL syntax',
412 | 'type': 'WDL',
413 | 'creationTime': creation_time,
414 | }
415 |
416 | # Mock context and client
417 | mock_ctx = AsyncMock()
418 | mock_client = MagicMock()
419 | mock_client.get_workflow.return_value = mock_response
420 |
421 | with patch(
422 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
423 | return_value=mock_client,
424 | ):
425 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
426 |
427 | # Verify status message is included
428 | assert result['status'] == 'FAILED'
429 | assert result['statusMessage'] == 'Workflow validation failed: Invalid WDL syntax'
430 |
431 |
432 | @pytest.mark.asyncio
433 | async def test_get_workflow_with_container_registry_map():
434 | """Test workflow retrieval with container registry map."""
435 | # Mock response with container registry map
436 | creation_time = datetime.now(timezone.utc)
437 | container_registry_map = {
438 | 'registryMappings': [
439 | {'upstreamRegistryUrl': 'registry-1.docker.io', 'ecrRepositoryPrefix': 'docker-hub'},
440 | {'upstreamRegistryUrl': 'quay.io', 'ecrRepositoryPrefix': 'quay'},
441 | ]
442 | }
443 | mock_response = {
444 | 'id': 'wfl-12345',
445 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
446 | 'name': 'test-workflow',
447 | 'status': 'ACTIVE',
448 | 'type': 'WDL',
449 | 'description': 'Test workflow with container registry map',
450 | 'parameterTemplate': {'param1': {'type': 'string'}},
451 | 'containerRegistryMap': container_registry_map,
452 | 'creationTime': creation_time,
453 | }
454 |
455 | # Mock context and client
456 | mock_ctx = AsyncMock()
457 | mock_client = MagicMock()
458 | mock_client.get_workflow.return_value = mock_response
459 |
460 | with patch(
461 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
462 | return_value=mock_client,
463 | ):
464 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
465 |
466 | # Verify container registry map is included
467 | assert result['containerRegistryMap'] == container_registry_map
468 | assert (
469 | result['containerRegistryMap']['registryMappings'][0]['upstreamRegistryUrl']
470 | == 'registry-1.docker.io'
471 | )
472 | assert (
473 | result['containerRegistryMap']['registryMappings'][0]['ecrRepositoryPrefix']
474 | == 'docker-hub'
475 | )
476 | assert (
477 | result['containerRegistryMap']['registryMappings'][1]['upstreamRegistryUrl'] == 'quay.io'
478 | )
479 | assert result['containerRegistryMap']['registryMappings'][1]['ecrRepositoryPrefix'] == 'quay'
480 |
481 | # Verify other fields are present
482 | assert result['id'] == 'wfl-12345'
483 | assert result['status'] == 'ACTIVE'
484 | assert result['description'] == 'Test workflow with container registry map'
485 |
486 |
487 | @pytest.mark.asyncio
488 | async def test_get_workflow_without_container_registry_map():
489 | """Test workflow retrieval without container registry map."""
490 | # Mock response without container registry map
491 | creation_time = datetime.now(timezone.utc)
492 | mock_response = {
493 | 'id': 'wfl-12345',
494 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
495 | 'name': 'test-workflow',
496 | 'status': 'ACTIVE',
497 | 'type': 'WDL',
498 | 'description': 'Test workflow without container registry map',
499 | 'parameterTemplate': {'param1': {'type': 'string'}},
500 | 'creationTime': creation_time,
501 | }
502 |
503 | # Mock context and client
504 | mock_ctx = AsyncMock()
505 | mock_client = MagicMock()
506 | mock_client.get_workflow.return_value = mock_response
507 |
508 | with patch(
509 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
510 | return_value=mock_client,
511 | ):
512 | result = await get_workflow(ctx=mock_ctx, workflow_id='wfl-12345', export_definition=False)
513 |
514 | # Verify container registry map is not present
515 | assert 'containerRegistryMap' not in result
516 |
517 | # Verify other fields are present
518 | assert result['id'] == 'wfl-12345'
519 | assert result['status'] == 'ACTIVE'
520 | assert result['description'] == 'Test workflow without container registry map'
521 |
522 |
523 | @pytest.mark.asyncio
524 | async def test_list_workflow_versions_success(mock_omics_client, mock_context):
525 | """Test successful listing of workflow versions."""
526 | # Mock response from AWS
527 | mock_omics_client.list_workflow_versions.return_value = {
528 | 'items': [
529 | {
530 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/abc123/1.0',
531 | 'id': 'abc123',
532 | 'status': 'ACTIVE',
533 | 'type': 'WDL',
534 | 'name': 'Test Workflow',
535 | 'versionName': '1.0',
536 | 'creationTime': '2023-01-01T00:00:00Z',
537 | },
538 | {
539 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/abc123/2.0',
540 | 'id': 'abc123',
541 | 'status': 'ACTIVE',
542 | 'type': 'WDL',
543 | 'name': 'Test Workflow',
544 | 'versionName': '2.0',
545 | 'creationTime': '2023-02-01T00:00:00Z',
546 | },
547 | ],
548 | 'nextToken': None,
549 | }
550 |
551 | with patch(
552 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
553 | return_value=mock_omics_client,
554 | ):
555 | # Call the function
556 | result = await list_workflow_versions(mock_context, workflow_id='abc123', max_results=10)
557 |
558 | # Assertions
559 | assert 'versions' in result
560 | assert len(result['versions']) == 2
561 | assert result['versions'][0]['versionName'] == '1.0'
562 | assert result['versions'][1]['versionName'] == '2.0'
563 | assert result['nextToken'] is None
564 |
565 |
566 | @pytest.mark.asyncio
567 | async def test_list_workflow_versions_with_pagination(mock_omics_client, mock_context):
568 | """Test listing workflow versions with pagination."""
569 | # First call response with nextToken
570 | mock_omics_client.list_workflow_versions.side_effect = [
571 | {
572 | 'items': [
573 | {
574 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/abc123/1.0',
575 | 'id': 'abc123',
576 | 'status': 'ACTIVE',
577 | 'type': 'WDL',
578 | 'name': 'Test Workflow',
579 | 'versionName': '1.0',
580 | 'creationTime': '2023-01-01T00:00:00Z',
581 | }
582 | ],
583 | 'nextToken': 'next-page-token',
584 | },
585 | {
586 | 'items': [
587 | {
588 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/abc123/2.0',
589 | 'id': 'abc123',
590 | 'status': 'ACTIVE',
591 | 'type': 'WDL',
592 | 'name': 'Test Workflow',
593 | 'versionName': '2.0',
594 | 'creationTime': '2023-02-01T00:00:00Z',
595 | }
596 | ],
597 | 'nextToken': None,
598 | },
599 | ]
600 |
601 | with patch(
602 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
603 | return_value=mock_omics_client,
604 | ):
605 | # First call
606 | result1 = await list_workflow_versions(mock_context, workflow_id='abc123', max_results=1)
607 |
608 | # Second call with next token
609 | result2 = await list_workflow_versions(
610 | mock_context, workflow_id='abc123', max_results=1, next_token=result1['nextToken']
611 | )
612 |
613 | # Assertions for first call
614 | assert 'versions' in result1
615 | assert len(result1['versions']) == 1
616 | assert result1['versions'][0]['versionName'] == '1.0'
617 | assert result1['nextToken'] == 'next-page-token'
618 |
619 | # Assertions for second call
620 | assert 'versions' in result2
621 | assert len(result2['versions']) == 1
622 | assert result2['versions'][0]['versionName'] == '2.0'
623 | assert result2['nextToken'] is None
624 |
625 |
626 | @pytest.mark.asyncio
627 | async def test_list_workflow_versions_empty_result(mock_omics_client, mock_context):
628 | """Test listing workflow versions with empty result."""
629 | # Mock empty response
630 | mock_omics_client.list_workflow_versions.return_value = {
631 | 'items': [],
632 | 'nextToken': None,
633 | }
634 |
635 | with patch(
636 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
637 | return_value=mock_omics_client,
638 | ):
639 | # Call the function
640 | result = await list_workflow_versions(mock_context, workflow_id='abc123', max_results=10)
641 |
642 | # Assertions
643 | assert 'versions' in result
644 | assert len(result['versions']) == 0
645 | if 'nextToken' in result:
646 | assert result['nextToken'] is None
647 |
648 |
649 | @pytest.mark.asyncio
650 | async def test_list_workflow_versions_client_error(mock_omics_client, mock_context):
651 | """Test handling of client error when listing workflow versions."""
652 | from botocore.exceptions import ClientError
653 |
654 | # Mock client error
655 | error_response = {
656 | 'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Workflow not found'}
657 | }
658 | mock_omics_client.list_workflow_versions.side_effect = ClientError(
659 | error_response, # type: ignore
660 | 'ListWorkflowVersions',
661 | )
662 |
663 | with patch(
664 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
665 | return_value=mock_omics_client,
666 | ):
667 | # Call the function and expect it to raise an exception
668 | with pytest.raises(ClientError):
669 | await list_workflow_versions(mock_context, workflow_id='nonexistent-id')
670 |
671 | # Verify error was reported to context
672 | mock_context.error.assert_called_once()
673 | assert 'Workflow not found' in mock_context.error.call_args[0][0]
674 |
675 |
676 | @pytest.mark.asyncio
677 | async def test_list_workflow_versions_general_exception(mock_omics_client, mock_context):
678 | """Test handling of general exception when listing workflow versions."""
679 | # Mock general exception
680 | mock_omics_client.list_workflow_versions.side_effect = Exception('Unexpected error')
681 |
682 | with patch(
683 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
684 | return_value=mock_omics_client,
685 | ):
686 | # Call the function and expect it to raise an exception
687 | with pytest.raises(Exception):
688 | await list_workflow_versions(mock_context, workflow_id='abc123')
689 |
690 | # Verify error was reported to context
691 | mock_context.error.assert_called_once()
692 | assert 'Unexpected error listing workflow versions' in mock_context.error.call_args[0][0]
693 |
694 |
695 | @pytest.mark.asyncio
696 | async def test_create_workflow_success():
697 | """Test successful workflow creation."""
698 | # Mock response data
699 | mock_response = {
700 | 'id': 'wfl-12345',
701 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
702 | 'status': 'ACTIVE',
703 | 'name': 'test-workflow',
704 | 'description': 'Test workflow description',
705 | }
706 |
707 | # Mock context and client
708 | mock_ctx = AsyncMock()
709 | mock_client = MagicMock()
710 | mock_client.create_workflow.return_value = mock_response
711 |
712 | # Create base64 encoded workflow definition
713 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
714 |
715 | with patch(
716 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
717 | return_value=mock_client,
718 | ):
719 | result = await create_workflow(
720 | mock_ctx,
721 | name='test-workflow',
722 | definition_zip_base64=definition_zip_base64,
723 | description='Test workflow description',
724 | parameter_template={'param1': {'type': 'string'}},
725 | container_registry_map=None,
726 | container_registry_map_uri=None,
727 | )
728 |
729 | # Verify client was called correctly
730 | mock_client.create_workflow.assert_called_once_with(
731 | name='test-workflow',
732 | definitionZip=b'test workflow content',
733 | description='Test workflow description',
734 | parameterTemplate={'param1': {'type': 'string'}},
735 | )
736 |
737 | # Verify result contains expected fields
738 | assert result['id'] == 'wfl-12345'
739 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
740 | assert result['status'] == 'ACTIVE'
741 | assert result['name'] == 'test-workflow'
742 | assert result['description'] == 'Test workflow description'
743 |
744 |
745 | @pytest.mark.asyncio
746 | async def test_create_workflow_minimal():
747 | """Test workflow creation with minimal required parameters."""
748 | # Mock response data
749 | mock_response = {
750 | 'id': 'wfl-12345',
751 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
752 | 'status': 'ACTIVE',
753 | 'name': 'test-workflow',
754 | }
755 |
756 | # Mock context and client
757 | mock_ctx = AsyncMock()
758 | mock_client = MagicMock()
759 | mock_client.create_workflow.return_value = mock_response
760 |
761 | # Create base64 encoded workflow definition
762 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
763 |
764 | with patch(
765 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
766 | return_value=mock_client,
767 | ):
768 | result = await create_workflow(
769 | mock_ctx,
770 | name='test-workflow',
771 | definition_zip_base64=definition_zip_base64,
772 | description=None,
773 | parameter_template=None,
774 | container_registry_map=None,
775 | container_registry_map_uri=None,
776 | )
777 |
778 | # Verify client was called with only required parameters
779 | mock_client.create_workflow.assert_called_once_with(
780 | name='test-workflow',
781 | definitionZip=b'test workflow content',
782 | )
783 |
784 | # Verify result contains expected fields
785 | assert result['id'] == 'wfl-12345'
786 | assert result['name'] == 'test-workflow'
787 | # description should not be in result when it's None in response
788 | assert result.get('description') is None
789 |
790 |
791 | @pytest.mark.asyncio
792 | async def test_create_workflow_invalid_base64():
793 | """Test workflow creation with invalid base64 content."""
794 | # Mock context
795 | mock_ctx = AsyncMock()
796 |
797 | with pytest.raises(Exception, match='Invalid base64-encoded string'):
798 | await create_workflow(
799 | mock_ctx,
800 | name='test-workflow',
801 | definition_zip_base64='invalid base64!',
802 | description=None,
803 | parameter_template=None,
804 | container_registry_map=None,
805 | container_registry_map_uri=None,
806 | )
807 |
808 | # Verify error was reported to context
809 | mock_ctx.error.assert_called_once()
810 | assert 'Failed to decode base64' in mock_ctx.error.call_args[0][0]
811 |
812 |
813 | @pytest.mark.asyncio
814 | async def test_create_workflow_boto_error():
815 | """Test handling of BotoCoreError in create_workflow."""
816 | # Mock context and client
817 | mock_ctx = AsyncMock()
818 | mock_client = MagicMock()
819 | mock_client.create_workflow.side_effect = botocore.exceptions.BotoCoreError()
820 |
821 | # Create base64 encoded workflow definition
822 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
823 |
824 | with (
825 | patch(
826 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
827 | return_value=mock_client,
828 | ),
829 | pytest.raises(botocore.exceptions.BotoCoreError),
830 | ):
831 | await create_workflow(
832 | mock_ctx,
833 | name='test-workflow',
834 | definition_zip_base64=definition_zip_base64,
835 | description=None,
836 | parameter_template=None,
837 | container_registry_map=None,
838 | container_registry_map_uri=None,
839 | )
840 |
841 | # Verify error was reported to context
842 | mock_ctx.error.assert_called_once()
843 | assert 'AWS error creating workflow' in mock_ctx.error.call_args[0][0]
844 |
845 |
846 | @pytest.mark.asyncio
847 | async def test_create_workflow_unexpected_error():
848 | """Test handling of unexpected errors in create_workflow."""
849 | # Mock context and client
850 | mock_ctx = AsyncMock()
851 | mock_client = MagicMock()
852 | mock_client.create_workflow.side_effect = Exception('Unexpected error')
853 |
854 | # Create base64 encoded workflow definition
855 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
856 |
857 | with (
858 | patch(
859 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
860 | return_value=mock_client,
861 | ),
862 | pytest.raises(Exception, match='Unexpected error'),
863 | ):
864 | await create_workflow(
865 | mock_ctx,
866 | name='test-workflow',
867 | definition_zip_base64=definition_zip_base64,
868 | description=None,
869 | parameter_template=None,
870 | container_registry_map=None,
871 | container_registry_map_uri=None,
872 | )
873 |
874 | # Verify error was reported to context
875 | mock_ctx.error.assert_called_once()
876 | assert 'Unexpected error creating workflow' in mock_ctx.error.call_args[0][0]
877 |
878 |
879 | @pytest.mark.asyncio
880 | async def test_create_workflow_with_container_registry_map():
881 | """Test workflow creation with container registry map."""
882 | # Mock response data
883 | mock_response = {
884 | 'id': 'wfl-12345',
885 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
886 | 'status': 'ACTIVE',
887 | 'name': 'test-workflow',
888 | 'description': 'Test workflow with container registry map',
889 | }
890 |
891 | # Mock context and client
892 | mock_ctx = AsyncMock()
893 | mock_client = MagicMock()
894 | mock_client.create_workflow.return_value = mock_response
895 |
896 | # Create base64 encoded workflow definition
897 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
898 |
899 | # Container registry map - using complete structure with all required fields
900 | container_registry_map = {
901 | 'registryMappings': [
902 | {
903 | 'upstreamRegistryUrl': 'registry-1.docker.io',
904 | 'ecrRepositoryPrefix': 'docker-hub',
905 | 'upstreamRepositoryPrefix': 'library',
906 | 'ecrAccountId': '123456789012',
907 | },
908 | {
909 | 'upstreamRegistryUrl': 'quay.io',
910 | 'ecrRepositoryPrefix': 'quay',
911 | 'upstreamRepositoryPrefix': 'biocontainers',
912 | 'ecrAccountId': '123456789012',
913 | },
914 | ]
915 | }
916 |
917 | with patch(
918 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
919 | return_value=mock_client,
920 | ):
921 | result = await create_workflow(
922 | mock_ctx,
923 | name='test-workflow',
924 | definition_zip_base64=definition_zip_base64,
925 | description='Test workflow with container registry map',
926 | parameter_template={'param1': {'type': 'string'}},
927 | container_registry_map=container_registry_map,
928 | container_registry_map_uri=None,
929 | )
930 |
931 | # Verify client was called correctly with container registry map
932 | mock_client.create_workflow.assert_called_once_with(
933 | name='test-workflow',
934 | definitionZip=b'test workflow content',
935 | description='Test workflow with container registry map',
936 | parameterTemplate={'param1': {'type': 'string'}},
937 | containerRegistryMap=container_registry_map,
938 | )
939 |
940 | # Verify result contains expected fields
941 | assert result['id'] == 'wfl-12345'
942 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
943 | assert result['status'] == 'ACTIVE'
944 | assert result['name'] == 'test-workflow'
945 | assert result['description'] == 'Test workflow with container registry map'
946 |
947 |
948 | @pytest.mark.asyncio
949 | async def test_create_workflow_without_container_registry_map():
950 | """Test workflow creation without container registry map."""
951 | # Mock response data
952 | mock_response = {
953 | 'id': 'wfl-12345',
954 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
955 | 'status': 'ACTIVE',
956 | 'name': 'test-workflow',
957 | }
958 |
959 | # Mock context and client
960 | mock_ctx = AsyncMock()
961 | mock_client = MagicMock()
962 | mock_client.create_workflow.return_value = mock_response
963 |
964 | # Create base64 encoded workflow definition
965 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
966 |
967 | with patch(
968 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
969 | return_value=mock_client,
970 | ):
971 | result = await create_workflow(
972 | mock_ctx,
973 | name='test-workflow',
974 | definition_zip_base64=definition_zip_base64,
975 | description=None,
976 | parameter_template=None,
977 | container_registry_map=None,
978 | container_registry_map_uri=None,
979 | )
980 |
981 | # Verify client was called without container registry map
982 | mock_client.create_workflow.assert_called_once_with(
983 | name='test-workflow',
984 | definitionZip=b'test workflow content',
985 | )
986 |
987 | # Verify result contains expected fields
988 | assert result['id'] == 'wfl-12345'
989 | assert result['name'] == 'test-workflow'
990 |
991 |
992 | @pytest.mark.asyncio
993 | async def test_create_workflow_with_container_registry_map_uri():
994 | """Test workflow creation with container registry map URI."""
995 | # Mock response data
996 | mock_response = {
997 | 'id': 'wfl-12345',
998 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
999 | 'status': 'ACTIVE',
1000 | 'name': 'test-workflow',
1001 | 'description': 'Test workflow with container registry map URI',
1002 | }
1003 |
1004 | # Mock context and client
1005 | mock_ctx = AsyncMock()
1006 | mock_client = MagicMock()
1007 | mock_client.create_workflow.return_value = mock_response
1008 |
1009 | # Create base64 encoded workflow definition
1010 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
1011 |
1012 | # S3 URI for container registry map
1013 | container_registry_map_uri = 's3://my-bucket/registry-mappings.json'
1014 |
1015 | with patch(
1016 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1017 | return_value=mock_client,
1018 | ):
1019 | result = await create_workflow(
1020 | mock_ctx,
1021 | name='test-workflow',
1022 | definition_zip_base64=definition_zip_base64,
1023 | description='Test workflow with container registry map URI',
1024 | parameter_template={'param1': {'type': 'string'}},
1025 | container_registry_map=None,
1026 | container_registry_map_uri=container_registry_map_uri,
1027 | )
1028 |
1029 | # Verify client was called correctly with container registry map URI
1030 | mock_client.create_workflow.assert_called_once_with(
1031 | name='test-workflow',
1032 | definitionZip=b'test workflow content',
1033 | description='Test workflow with container registry map URI',
1034 | parameterTemplate={'param1': {'type': 'string'}},
1035 | containerRegistryMapUri=container_registry_map_uri,
1036 | )
1037 |
1038 | # Verify result contains expected fields
1039 | assert result['id'] == 'wfl-12345'
1040 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
1041 | assert result['status'] == 'ACTIVE'
1042 | assert result['name'] == 'test-workflow'
1043 | assert result['description'] == 'Test workflow with container registry map URI'
1044 |
1045 |
1046 | @pytest.mark.asyncio
1047 | async def test_create_workflow_invalid_container_registry_map():
1048 | """Test workflow creation with invalid container registry map structure."""
1049 | # Mock context
1050 | mock_ctx = AsyncMock()
1051 |
1052 | # Create base64 encoded workflow definition
1053 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
1054 |
1055 | # Invalid container registry map - missing required fields
1056 | invalid_container_registry_map = {
1057 | 'registryMappings': [
1058 | {'upstreamRegistryUrl': 'registry-1.docker.io'} # Missing required fields
1059 | ]
1060 | }
1061 |
1062 | # Should raise ValueError due to validation error
1063 | with pytest.raises(ValueError, match='Invalid container registry map structure'):
1064 | await create_workflow(
1065 | mock_ctx,
1066 | name='test-workflow',
1067 | definition_zip_base64=definition_zip_base64,
1068 | container_registry_map=invalid_container_registry_map,
1069 | container_registry_map_uri=None,
1070 | )
1071 |
1072 |
1073 | @pytest.mark.asyncio
1074 | async def test_create_workflow_both_container_registry_params_error():
1075 | """Test workflow creation fails when both container registry parameters are provided."""
1076 | # Mock context
1077 | mock_ctx = AsyncMock()
1078 |
1079 | # Create base64 encoded workflow definition
1080 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
1081 |
1082 | # Container registry map
1083 | container_registry_map = {
1084 | 'registryMappings': [
1085 | {'upstreamRegistryUrl': 'registry-1.docker.io', 'ecrRepositoryPrefix': 'docker-hub'}
1086 | ]
1087 | }
1088 |
1089 | # S3 URI for container registry map
1090 | container_registry_map_uri = 's3://my-bucket/registry-mappings.json'
1091 |
1092 | with pytest.raises(
1093 | ValueError,
1094 | match='Cannot specify both container_registry_map and container_registry_map_uri parameters',
1095 | ):
1096 | await create_workflow(
1097 | mock_ctx,
1098 | name='test-workflow',
1099 | definition_zip_base64=definition_zip_base64,
1100 | description=None,
1101 | parameter_template=None,
1102 | container_registry_map=container_registry_map,
1103 | container_registry_map_uri=container_registry_map_uri,
1104 | )
1105 |
1106 | # Verify error was reported to context
1107 | mock_ctx.error.assert_called_once()
1108 | assert (
1109 | 'Cannot specify both container_registry_map and container_registry_map_uri parameters'
1110 | in mock_ctx.error.call_args[0][0]
1111 | )
1112 |
1113 |
1114 | @pytest.mark.asyncio
1115 | async def test_create_workflow_version_success():
1116 | """Test successful workflow version creation."""
1117 | # Mock response data
1118 | mock_response = {
1119 | 'id': 'wfl-12345',
1120 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1121 | 'status': 'ACTIVE',
1122 | 'name': 'test-workflow',
1123 | 'versionName': 'v2.0',
1124 | }
1125 |
1126 | # Mock context and client
1127 | mock_ctx = AsyncMock()
1128 | mock_client = MagicMock()
1129 | mock_client.create_workflow_version.return_value = mock_response
1130 |
1131 | # Create base64 encoded workflow definition
1132 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1133 |
1134 | with patch(
1135 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1136 | return_value=mock_client,
1137 | ):
1138 | result = await create_workflow_version(
1139 | mock_ctx,
1140 | workflow_id='wfl-12345',
1141 | version_name='v2.0',
1142 | definition_zip_base64=definition_zip_base64,
1143 | description='Version 2.0 of test workflow',
1144 | parameter_template={'param1': {'type': 'string'}},
1145 | storage_type='DYNAMIC',
1146 | storage_capacity=None,
1147 | container_registry_map=None,
1148 | container_registry_map_uri=None,
1149 | )
1150 |
1151 | # Verify client was called correctly
1152 | mock_client.create_workflow_version.assert_called_once_with(
1153 | workflowId='wfl-12345',
1154 | versionName='v2.0',
1155 | definitionZip=b'test workflow content v2',
1156 | description='Version 2.0 of test workflow',
1157 | parameterTemplate={'param1': {'type': 'string'}},
1158 | storageType='DYNAMIC',
1159 | )
1160 |
1161 | # Verify result contains expected fields
1162 | assert result['id'] == 'wfl-12345'
1163 | assert result['versionName'] == 'v2.0'
1164 | assert result['status'] == 'ACTIVE'
1165 |
1166 |
1167 | @pytest.mark.asyncio
1168 | async def test_create_workflow_version_with_static_storage():
1169 | """Test workflow version creation with static storage."""
1170 | # Mock response data
1171 | mock_response = {
1172 | 'id': 'wfl-12345',
1173 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1174 | 'status': 'ACTIVE',
1175 | 'name': 'test-workflow',
1176 | 'versionName': 'v2.0',
1177 | }
1178 |
1179 | # Mock context and client
1180 | mock_ctx = AsyncMock()
1181 | mock_client = MagicMock()
1182 | mock_client.create_workflow_version.return_value = mock_response
1183 |
1184 | # Create base64 encoded workflow definition
1185 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1186 |
1187 | with patch(
1188 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1189 | return_value=mock_client,
1190 | ):
1191 | await create_workflow_version(
1192 | mock_ctx,
1193 | workflow_id='wfl-12345',
1194 | version_name='v2.0',
1195 | definition_zip_base64=definition_zip_base64,
1196 | description=None,
1197 | parameter_template=None,
1198 | storage_type='STATIC',
1199 | storage_capacity=1000,
1200 | container_registry_map=None,
1201 | container_registry_map_uri=None,
1202 | )
1203 |
1204 | # Verify client was called with static storage parameters
1205 | mock_client.create_workflow_version.assert_called_once_with(
1206 | workflowId='wfl-12345',
1207 | versionName='v2.0',
1208 | definitionZip=b'test workflow content v2',
1209 | storageType='STATIC',
1210 | storageCapacity=1000,
1211 | )
1212 |
1213 |
1214 | @pytest.mark.asyncio
1215 | async def test_create_workflow_version_static_without_capacity():
1216 | """Test workflow version creation with static storage but no capacity."""
1217 | # Mock context
1218 | mock_ctx = AsyncMock()
1219 |
1220 | # Create base64 encoded workflow definition
1221 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1222 |
1223 | with pytest.raises(ValueError, match='Storage capacity is required'):
1224 | await create_workflow_version(
1225 | mock_ctx,
1226 | workflow_id='wfl-12345',
1227 | version_name='v2.0',
1228 | definition_zip_base64=definition_zip_base64,
1229 | description=None,
1230 | parameter_template=None,
1231 | storage_type='STATIC',
1232 | storage_capacity=None,
1233 | container_registry_map=None,
1234 | container_registry_map_uri=None,
1235 | )
1236 |
1237 | # Verify error was reported to context
1238 | mock_ctx.error.assert_called_once()
1239 |
1240 |
1241 | @pytest.mark.asyncio
1242 | async def test_create_workflow_version_invalid_base64():
1243 | """Test workflow version creation with invalid base64 content."""
1244 | # Mock context
1245 | mock_ctx = AsyncMock()
1246 |
1247 | with pytest.raises(Exception, match='Invalid base64-encoded string'):
1248 | await create_workflow_version(
1249 | mock_ctx,
1250 | workflow_id='wfl-12345',
1251 | version_name='v2.0',
1252 | definition_zip_base64='invalid base64!',
1253 | description=None,
1254 | parameter_template=None,
1255 | storage_type='DYNAMIC',
1256 | storage_capacity=None,
1257 | container_registry_map=None,
1258 | container_registry_map_uri=None,
1259 | )
1260 |
1261 | # Verify error was reported to context
1262 | mock_ctx.error.assert_called_once()
1263 | assert 'Failed to decode base64' in mock_ctx.error.call_args[0][0]
1264 |
1265 |
1266 | @pytest.mark.asyncio
1267 | async def test_create_workflow_version_boto_error():
1268 | """Test handling of BotoCoreError in create_workflow_version."""
1269 | # Mock context and client
1270 | mock_ctx = AsyncMock()
1271 | mock_client = MagicMock()
1272 | mock_client.create_workflow_version.side_effect = botocore.exceptions.BotoCoreError()
1273 |
1274 | # Create base64 encoded workflow definition
1275 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1276 |
1277 | with (
1278 | patch(
1279 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1280 | return_value=mock_client,
1281 | ),
1282 | pytest.raises(botocore.exceptions.BotoCoreError),
1283 | ):
1284 | await create_workflow_version(
1285 | mock_ctx,
1286 | workflow_id='wfl-12345',
1287 | version_name='v2.0',
1288 | definition_zip_base64=definition_zip_base64,
1289 | description=None,
1290 | parameter_template=None,
1291 | storage_type='DYNAMIC',
1292 | storage_capacity=None,
1293 | container_registry_map=None,
1294 | container_registry_map_uri=None,
1295 | )
1296 |
1297 | # Verify error was reported to context
1298 | mock_ctx.error.assert_called_once()
1299 | assert 'AWS error creating workflow version' in mock_ctx.error.call_args[0][0]
1300 |
1301 |
1302 | @pytest.mark.asyncio
1303 | async def test_create_workflow_version_with_container_registry_map():
1304 | """Test workflow version creation with container registry map."""
1305 | # Mock response data
1306 | mock_response = {
1307 | 'id': 'wfl-12345',
1308 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1309 | 'status': 'ACTIVE',
1310 | 'name': 'test-workflow',
1311 | 'versionName': 'v2.0',
1312 | }
1313 |
1314 | # Mock context and client
1315 | mock_ctx = AsyncMock()
1316 | mock_client = MagicMock()
1317 | mock_client.create_workflow_version.return_value = mock_response
1318 |
1319 | # Create base64 encoded workflow definition
1320 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1321 |
1322 | # Container registry map - using complete structure with all required fields
1323 | container_registry_map = {
1324 | 'registryMappings': [
1325 | {
1326 | 'upstreamRegistryUrl': 'registry-1.docker.io',
1327 | 'ecrRepositoryPrefix': 'docker-hub',
1328 | 'upstreamRepositoryPrefix': 'library',
1329 | 'ecrAccountId': '123456789012',
1330 | },
1331 | {
1332 | 'upstreamRegistryUrl': 'quay.io',
1333 | 'ecrRepositoryPrefix': 'quay',
1334 | 'upstreamRepositoryPrefix': 'biocontainers',
1335 | 'ecrAccountId': '123456789012',
1336 | },
1337 | ]
1338 | }
1339 |
1340 | with patch(
1341 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1342 | return_value=mock_client,
1343 | ):
1344 | result = await create_workflow_version(
1345 | mock_ctx,
1346 | workflow_id='wfl-12345',
1347 | version_name='v2.0',
1348 | definition_zip_base64=definition_zip_base64,
1349 | description='Version 2.0 with container registry map',
1350 | parameter_template={'param1': {'type': 'string'}},
1351 | storage_type='DYNAMIC',
1352 | storage_capacity=None,
1353 | container_registry_map=container_registry_map,
1354 | container_registry_map_uri=None,
1355 | )
1356 |
1357 | # Verify client was called correctly with container registry map
1358 | mock_client.create_workflow_version.assert_called_once_with(
1359 | workflowId='wfl-12345',
1360 | versionName='v2.0',
1361 | definitionZip=b'test workflow content v2',
1362 | description='Version 2.0 with container registry map',
1363 | parameterTemplate={'param1': {'type': 'string'}},
1364 | storageType='DYNAMIC',
1365 | containerRegistryMap=container_registry_map,
1366 | )
1367 |
1368 | # Verify result contains expected fields
1369 | assert result['id'] == 'wfl-12345'
1370 | assert result['versionName'] == 'v2.0'
1371 | assert result['status'] == 'ACTIVE'
1372 |
1373 |
1374 | @pytest.mark.asyncio
1375 | async def test_create_workflow_version_without_container_registry_map():
1376 | """Test workflow version creation without container registry map."""
1377 | # Mock response data
1378 | mock_response = {
1379 | 'id': 'wfl-12345',
1380 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1381 | 'status': 'ACTIVE',
1382 | 'name': 'test-workflow',
1383 | 'versionName': 'v2.0',
1384 | }
1385 |
1386 | # Mock context and client
1387 | mock_ctx = AsyncMock()
1388 | mock_client = MagicMock()
1389 | mock_client.create_workflow_version.return_value = mock_response
1390 |
1391 | # Create base64 encoded workflow definition
1392 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1393 |
1394 | with patch(
1395 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1396 | return_value=mock_client,
1397 | ):
1398 | result = await create_workflow_version(
1399 | mock_ctx,
1400 | workflow_id='wfl-12345',
1401 | version_name='v2.0',
1402 | definition_zip_base64=definition_zip_base64,
1403 | description='Version 2.0 without container registry map',
1404 | parameter_template={'param1': {'type': 'string'}},
1405 | storage_type='DYNAMIC',
1406 | storage_capacity=None,
1407 | container_registry_map=None,
1408 | container_registry_map_uri=None,
1409 | )
1410 |
1411 | # Verify client was called without container registry map
1412 | mock_client.create_workflow_version.assert_called_once_with(
1413 | workflowId='wfl-12345',
1414 | versionName='v2.0',
1415 | definitionZip=b'test workflow content v2',
1416 | description='Version 2.0 without container registry map',
1417 | parameterTemplate={'param1': {'type': 'string'}},
1418 | storageType='DYNAMIC',
1419 | )
1420 |
1421 | # Verify result contains expected fields
1422 | assert result['id'] == 'wfl-12345'
1423 | assert result['versionName'] == 'v2.0'
1424 | assert result['status'] == 'ACTIVE'
1425 |
1426 |
1427 | @pytest.mark.asyncio
1428 | async def test_create_workflow_version_with_static_storage_and_container_registry_map():
1429 | """Test workflow version creation with both static storage and container registry map."""
1430 | # Mock response data
1431 | mock_response = {
1432 | 'id': 'wfl-12345',
1433 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1434 | 'status': 'ACTIVE',
1435 | 'name': 'test-workflow',
1436 | 'versionName': 'v2.0',
1437 | }
1438 |
1439 | # Mock context and client
1440 | mock_ctx = AsyncMock()
1441 | mock_client = MagicMock()
1442 | mock_client.create_workflow_version.return_value = mock_response
1443 |
1444 | # Create base64 encoded workflow definition
1445 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1446 |
1447 | # Container registry map - using complete structure with all required fields
1448 | container_registry_map = {
1449 | 'registryMappings': [
1450 | {
1451 | 'upstreamRegistryUrl': 'registry-1.docker.io',
1452 | 'ecrRepositoryPrefix': 'docker-hub',
1453 | 'upstreamRepositoryPrefix': 'library',
1454 | 'ecrAccountId': '123456789012',
1455 | }
1456 | ]
1457 | }
1458 |
1459 | with patch(
1460 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1461 | return_value=mock_client,
1462 | ):
1463 | result = await create_workflow_version(
1464 | mock_ctx,
1465 | workflow_id='wfl-12345',
1466 | version_name='v2.0',
1467 | definition_zip_base64=definition_zip_base64,
1468 | description='Version 2.0 with static storage and container registry map',
1469 | parameter_template=None,
1470 | storage_type='STATIC',
1471 | storage_capacity=2000,
1472 | container_registry_map=container_registry_map,
1473 | container_registry_map_uri=None,
1474 | )
1475 |
1476 | # Verify client was called with both static storage and container registry map
1477 | mock_client.create_workflow_version.assert_called_once_with(
1478 | workflowId='wfl-12345',
1479 | versionName='v2.0',
1480 | definitionZip=b'test workflow content v2',
1481 | description='Version 2.0 with static storage and container registry map',
1482 | storageType='STATIC',
1483 | storageCapacity=2000,
1484 | containerRegistryMap=container_registry_map,
1485 | )
1486 |
1487 | # Verify result contains expected fields
1488 | assert result['id'] == 'wfl-12345'
1489 | assert result['versionName'] == 'v2.0'
1490 | assert result['status'] == 'ACTIVE'
1491 |
1492 |
1493 | @pytest.mark.asyncio
1494 | async def test_create_workflow_version_with_container_registry_map_uri():
1495 | """Test workflow version creation with container registry map URI."""
1496 | # Mock response data
1497 | mock_response = {
1498 | 'id': 'wfl-12345',
1499 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1500 | 'status': 'ACTIVE',
1501 | 'name': 'test-workflow',
1502 | 'versionName': 'v2.0',
1503 | }
1504 |
1505 | # Mock context and client
1506 | mock_ctx = AsyncMock()
1507 | mock_client = MagicMock()
1508 | mock_client.create_workflow_version.return_value = mock_response
1509 |
1510 | # Create base64 encoded workflow definition
1511 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1512 |
1513 | # S3 URI for container registry map
1514 | container_registry_map_uri = 's3://my-bucket/registry-mappings.json'
1515 |
1516 | with patch(
1517 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1518 | return_value=mock_client,
1519 | ):
1520 | result = await create_workflow_version(
1521 | mock_ctx,
1522 | workflow_id='wfl-12345',
1523 | version_name='v2.0',
1524 | definition_zip_base64=definition_zip_base64,
1525 | description='Version 2.0 with container registry map URI',
1526 | parameter_template={'param1': {'type': 'string'}},
1527 | storage_type='DYNAMIC',
1528 | storage_capacity=None,
1529 | container_registry_map=None,
1530 | container_registry_map_uri=container_registry_map_uri,
1531 | )
1532 |
1533 | # Verify client was called correctly with container registry map URI
1534 | mock_client.create_workflow_version.assert_called_once_with(
1535 | workflowId='wfl-12345',
1536 | versionName='v2.0',
1537 | definitionZip=b'test workflow content v2',
1538 | description='Version 2.0 with container registry map URI',
1539 | parameterTemplate={'param1': {'type': 'string'}},
1540 | storageType='DYNAMIC',
1541 | containerRegistryMapUri=container_registry_map_uri,
1542 | )
1543 |
1544 | # Verify result contains expected fields
1545 | assert result['id'] == 'wfl-12345'
1546 | assert result['versionName'] == 'v2.0'
1547 | assert result['status'] == 'ACTIVE'
1548 |
1549 |
1550 | @pytest.mark.asyncio
1551 | async def test_create_workflow_version_both_container_registry_params_error():
1552 | """Test workflow version creation fails when both container registry parameters are provided."""
1553 | # Mock context
1554 | mock_ctx = AsyncMock()
1555 |
1556 | # Create base64 encoded workflow definition
1557 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1558 |
1559 | # Container registry map
1560 | container_registry_map = {
1561 | 'registryMappings': [
1562 | {'upstreamRegistryUrl': 'registry-1.docker.io', 'ecrRepositoryPrefix': 'docker-hub'}
1563 | ]
1564 | }
1565 |
1566 | # S3 URI for container registry map
1567 | container_registry_map_uri = 's3://my-bucket/registry-mappings.json'
1568 |
1569 | with pytest.raises(
1570 | ValueError,
1571 | match='Cannot specify both container_registry_map and container_registry_map_uri parameters',
1572 | ):
1573 | await create_workflow_version(
1574 | mock_ctx,
1575 | workflow_id='wfl-12345',
1576 | version_name='v2.0',
1577 | definition_zip_base64=definition_zip_base64,
1578 | description=None,
1579 | parameter_template=None,
1580 | storage_type='DYNAMIC',
1581 | storage_capacity=None,
1582 | container_registry_map=container_registry_map,
1583 | container_registry_map_uri=container_registry_map_uri,
1584 | )
1585 |
1586 | # Verify error was reported to context
1587 | mock_ctx.error.assert_called_once()
1588 | assert (
1589 | 'Cannot specify both container_registry_map and container_registry_map_uri parameters'
1590 | in mock_ctx.error.call_args[0][0]
1591 | )
1592 |
1593 |
1594 | # Tests for S3 URI support in create_workflow
1595 |
1596 |
1597 | @pytest.mark.asyncio
1598 | async def test_create_workflow_with_s3_uri():
1599 | """Test successful workflow creation with S3 URI."""
1600 | # Mock response data
1601 | mock_response = {
1602 | 'id': 'wfl-12345',
1603 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1604 | 'status': 'ACTIVE',
1605 | 'name': 'test-workflow',
1606 | 'description': 'Test workflow description',
1607 | }
1608 |
1609 | # Mock context and client
1610 | mock_ctx = AsyncMock()
1611 | mock_client = MagicMock()
1612 | mock_client.create_workflow.return_value = mock_response
1613 |
1614 | with patch(
1615 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1616 | return_value=mock_client,
1617 | ):
1618 | result = await create_workflow(
1619 | mock_ctx,
1620 | name='test-workflow',
1621 | definition_zip_base64=None,
1622 | description='Test workflow description',
1623 | parameter_template={'param1': {'type': 'string'}},
1624 | container_registry_map=None,
1625 | container_registry_map_uri=None,
1626 | definition_uri='s3://my-bucket/workflow-definition.zip',
1627 | )
1628 |
1629 | # Verify client was called correctly with S3 URI
1630 | mock_client.create_workflow.assert_called_once_with(
1631 | name='test-workflow',
1632 | definitionUri='s3://my-bucket/workflow-definition.zip',
1633 | description='Test workflow description',
1634 | parameterTemplate={'param1': {'type': 'string'}},
1635 | )
1636 |
1637 | # Verify result contains expected fields
1638 | assert result['id'] == 'wfl-12345'
1639 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
1640 | assert result['status'] == 'ACTIVE'
1641 | assert result['name'] == 'test-workflow'
1642 | assert result['description'] == 'Test workflow description'
1643 |
1644 |
1645 | @pytest.mark.asyncio
1646 | async def test_create_workflow_both_definition_sources_error():
1647 | """Test error when both definition_zip_base64 and definition_uri are provided."""
1648 | # Mock context
1649 | mock_ctx = AsyncMock()
1650 |
1651 | # Create base64 encoded workflow definition
1652 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
1653 |
1654 | with pytest.raises(
1655 | ValueError, match='Cannot specify both definition_zip_base64 and definition_uri'
1656 | ):
1657 | await create_workflow(
1658 | mock_ctx,
1659 | name='test-workflow',
1660 | definition_zip_base64=definition_zip_base64,
1661 | description=None,
1662 | parameter_template=None,
1663 | container_registry_map=None,
1664 | container_registry_map_uri=None,
1665 | definition_uri='s3://my-bucket/workflow-definition.zip',
1666 | )
1667 |
1668 | # Verify error was reported to context
1669 | mock_ctx.error.assert_called_once()
1670 | assert (
1671 | 'Cannot specify both definition_zip_base64 and definition_uri'
1672 | in mock_ctx.error.call_args[0][0]
1673 | )
1674 |
1675 |
1676 | @pytest.mark.asyncio
1677 | async def test_create_workflow_no_definition_source_error():
1678 | """Test error when neither definition_zip_base64 nor definition_uri are provided."""
1679 | # Mock context
1680 | mock_ctx = AsyncMock()
1681 |
1682 | with pytest.raises(
1683 | ValueError, match='Must specify either definition_zip_base64 or definition_uri'
1684 | ):
1685 | await create_workflow(
1686 | mock_ctx,
1687 | name='test-workflow',
1688 | definition_zip_base64=None,
1689 | description=None,
1690 | parameter_template=None,
1691 | container_registry_map=None,
1692 | container_registry_map_uri=None,
1693 | definition_uri=None,
1694 | )
1695 |
1696 | # Verify error was reported to context
1697 | mock_ctx.error.assert_called_once()
1698 | assert (
1699 | 'Must specify either definition_zip_base64 or definition_uri'
1700 | in mock_ctx.error.call_args[0][0]
1701 | )
1702 |
1703 |
1704 | @pytest.mark.asyncio
1705 | async def test_create_workflow_invalid_s3_uri():
1706 | """Test error when definition_uri is not a valid S3 URI."""
1707 | # Mock context
1708 | mock_ctx = AsyncMock()
1709 |
1710 | with pytest.raises(ValueError, match='definition_uri must be a valid S3 URI'):
1711 | await create_workflow(
1712 | mock_ctx,
1713 | name='test-workflow',
1714 | definition_zip_base64=None,
1715 | description=None,
1716 | parameter_template=None,
1717 | container_registry_map=None,
1718 | container_registry_map_uri=None,
1719 | definition_uri='https://example.com/workflow.zip',
1720 | )
1721 |
1722 | # Verify error was reported to context
1723 | mock_ctx.error.assert_called_once()
1724 | assert 'definition_uri must be a valid S3 URI' in mock_ctx.error.call_args[0][0]
1725 |
1726 |
1727 | # Tests for S3 URI support in create_workflow_version
1728 |
1729 |
1730 | @pytest.mark.asyncio
1731 | async def test_create_workflow_version_with_s3_uri():
1732 | """Test successful workflow version creation with S3 URI."""
1733 | # Mock response data
1734 | mock_response = {
1735 | 'id': 'wfl-12345',
1736 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1737 | 'status': 'ACTIVE',
1738 | 'name': 'test-workflow',
1739 | 'versionName': 'v2.0',
1740 | 'description': 'Test workflow version description',
1741 | }
1742 |
1743 | # Mock context and client
1744 | mock_ctx = AsyncMock()
1745 | mock_client = MagicMock()
1746 | mock_client.create_workflow_version.return_value = mock_response
1747 |
1748 | with patch(
1749 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1750 | return_value=mock_client,
1751 | ):
1752 | result = await create_workflow_version(
1753 | mock_ctx,
1754 | workflow_id='wfl-12345',
1755 | version_name='v2.0',
1756 | definition_zip_base64=None,
1757 | description='Test workflow version description',
1758 | parameter_template={'param1': {'type': 'string'}},
1759 | storage_type='DYNAMIC',
1760 | storage_capacity=None,
1761 | container_registry_map=None,
1762 | container_registry_map_uri=None,
1763 | definition_uri='s3://my-bucket/workflow-definition-v2.zip',
1764 | )
1765 |
1766 | # Verify client was called correctly with S3 URI
1767 | mock_client.create_workflow_version.assert_called_once_with(
1768 | workflowId='wfl-12345',
1769 | versionName='v2.0',
1770 | definitionUri='s3://my-bucket/workflow-definition-v2.zip',
1771 | description='Test workflow version description',
1772 | parameterTemplate={'param1': {'type': 'string'}},
1773 | storageType='DYNAMIC',
1774 | )
1775 |
1776 | # Verify result contains expected fields
1777 | assert result['id'] == 'wfl-12345'
1778 | assert result['arn'] == 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345'
1779 | assert result['status'] == 'ACTIVE'
1780 | assert result['name'] == 'test-workflow'
1781 | assert result['versionName'] == 'v2.0'
1782 | assert result['description'] == 'Test workflow version description'
1783 |
1784 |
1785 | @pytest.mark.asyncio
1786 | async def test_create_workflow_version_both_definition_sources_error():
1787 | """Test error when both definition_zip_base64 and definition_uri are provided for version creation."""
1788 | # Mock context
1789 | mock_ctx = AsyncMock()
1790 |
1791 | # Create base64 encoded workflow definition
1792 | definition_zip_base64 = base64.b64encode(b'test workflow content').decode('utf-8')
1793 |
1794 | with pytest.raises(
1795 | ValueError, match='Cannot specify both definition_zip_base64 and definition_uri'
1796 | ):
1797 | await create_workflow_version(
1798 | mock_ctx,
1799 | workflow_id='wfl-12345',
1800 | version_name='v2.0',
1801 | definition_zip_base64=definition_zip_base64,
1802 | description=None,
1803 | parameter_template=None,
1804 | storage_type='DYNAMIC',
1805 | storage_capacity=None,
1806 | container_registry_map=None,
1807 | container_registry_map_uri=None,
1808 | definition_uri='s3://my-bucket/workflow-definition.zip',
1809 | )
1810 |
1811 | # Verify error was reported to context
1812 | mock_ctx.error.assert_called_once()
1813 | assert (
1814 | 'Cannot specify both definition_zip_base64 and definition_uri'
1815 | in mock_ctx.error.call_args[0][0]
1816 | )
1817 |
1818 |
1819 | @pytest.mark.asyncio
1820 | async def test_create_workflow_version_no_definition_source_error():
1821 | """Test error when neither definition_zip_base64 nor definition_uri are provided for version creation."""
1822 | # Mock context
1823 | mock_ctx = AsyncMock()
1824 |
1825 | with pytest.raises(
1826 | ValueError, match='Must specify either definition_zip_base64 or definition_uri'
1827 | ):
1828 | await create_workflow_version(
1829 | mock_ctx,
1830 | workflow_id='wfl-12345',
1831 | version_name='v2.0',
1832 | definition_zip_base64=None,
1833 | description=None,
1834 | parameter_template=None,
1835 | storage_type='DYNAMIC',
1836 | storage_capacity=None,
1837 | container_registry_map=None,
1838 | container_registry_map_uri=None,
1839 | definition_uri=None,
1840 | )
1841 |
1842 | # Verify error was reported to context
1843 | mock_ctx.error.assert_called_once()
1844 | assert (
1845 | 'Must specify either definition_zip_base64 or definition_uri'
1846 | in mock_ctx.error.call_args[0][0]
1847 | )
1848 |
1849 |
1850 | @pytest.mark.asyncio
1851 | async def test_create_workflow_version_invalid_container_registry_map():
1852 | """Test workflow version creation with invalid container registry map structure."""
1853 | # Mock context
1854 | mock_ctx = AsyncMock()
1855 |
1856 | # Create base64 encoded workflow definition
1857 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1858 |
1859 | # Invalid container registry map (missing required fields)
1860 | invalid_container_registry_map = {
1861 | 'registryMappings': [
1862 | {'invalidField': 'invalid-value'} # Missing required fields
1863 | ]
1864 | }
1865 |
1866 | with pytest.raises(ValueError, match='Invalid container registry map structure'):
1867 | await create_workflow_version(
1868 | mock_ctx,
1869 | workflow_id='wfl-12345',
1870 | version_name='v2.0',
1871 | definition_zip_base64=definition_zip_base64,
1872 | description=None,
1873 | parameter_template=None,
1874 | storage_type='DYNAMIC',
1875 | storage_capacity=None,
1876 | container_registry_map=invalid_container_registry_map,
1877 | container_registry_map_uri=None,
1878 | definition_uri=None,
1879 | )
1880 |
1881 | # Verify error was reported to context
1882 | mock_ctx.error.assert_called_once()
1883 | assert 'Invalid container registry map structure' in mock_ctx.error.call_args[0][0]
1884 |
1885 |
1886 | @pytest.mark.asyncio
1887 | async def test_create_workflow_version_invalid_s3_uri():
1888 | """Test error when definition_uri is not a valid S3 URI for version creation."""
1889 | # Mock context
1890 | mock_ctx = AsyncMock()
1891 |
1892 | with pytest.raises(ValueError, match='definition_uri must be a valid S3 URI'):
1893 | await create_workflow_version(
1894 | mock_ctx,
1895 | workflow_id='wfl-12345',
1896 | version_name='v2.0',
1897 | definition_zip_base64=None,
1898 | description=None,
1899 | parameter_template=None,
1900 | storage_type='DYNAMIC',
1901 | storage_capacity=None,
1902 | container_registry_map=None,
1903 | container_registry_map_uri=None,
1904 | definition_uri='https://example.com/workflow.zip',
1905 | )
1906 |
1907 | # Verify error was reported to context
1908 | mock_ctx.error.assert_called_once()
1909 | assert 'definition_uri must be a valid S3 URI' in mock_ctx.error.call_args[0][0]
1910 |
1911 |
1912 | @pytest.mark.asyncio
1913 | async def test_create_workflow_version_unexpected_error():
1914 | """Test handling of unexpected errors in create_workflow_version."""
1915 | # Mock context and client
1916 | mock_ctx = AsyncMock()
1917 | mock_client = MagicMock()
1918 | mock_client.create_workflow_version.side_effect = Exception('Unexpected error')
1919 |
1920 | # Create base64 encoded workflow definition
1921 | definition_zip_base64 = base64.b64encode(b'test workflow content v2').decode('utf-8')
1922 |
1923 | with (
1924 | patch(
1925 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1926 | return_value=mock_client,
1927 | ),
1928 | pytest.raises(Exception, match='Unexpected error'),
1929 | ):
1930 | await create_workflow_version(
1931 | mock_ctx,
1932 | workflow_id='wfl-12345',
1933 | version_name='v2.0',
1934 | definition_zip_base64=definition_zip_base64,
1935 | description=None,
1936 | parameter_template=None,
1937 | storage_type='DYNAMIC',
1938 | storage_capacity=None,
1939 | container_registry_map=None,
1940 | container_registry_map_uri=None,
1941 | definition_uri=None,
1942 | )
1943 |
1944 | # Verify error was reported to context
1945 | mock_ctx.error.assert_called_once()
1946 | assert 'Unexpected error creating workflow version' in mock_ctx.error.call_args[0][0]
1947 |
1948 |
1949 | @pytest.mark.asyncio
1950 | async def test_create_workflow_s3_uri_minimal():
1951 | """Test workflow creation with S3 URI and minimal parameters."""
1952 | # Mock response data
1953 | mock_response = {
1954 | 'id': 'wfl-12345',
1955 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1956 | 'status': 'ACTIVE',
1957 | 'name': 'test-workflow',
1958 | }
1959 |
1960 | # Mock context and client
1961 | mock_ctx = AsyncMock()
1962 | mock_client = MagicMock()
1963 | mock_client.create_workflow.return_value = mock_response
1964 |
1965 | with patch(
1966 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
1967 | return_value=mock_client,
1968 | ):
1969 | result = await create_workflow(
1970 | mock_ctx,
1971 | name='test-workflow',
1972 | definition_zip_base64=None,
1973 | description=None,
1974 | parameter_template=None,
1975 | container_registry_map=None,
1976 | container_registry_map_uri=None,
1977 | definition_uri='s3://my-bucket/workflow-definition.zip',
1978 | )
1979 |
1980 | # Verify client was called with only required parameters
1981 | mock_client.create_workflow.assert_called_once_with(
1982 | name='test-workflow',
1983 | definitionUri='s3://my-bucket/workflow-definition.zip',
1984 | )
1985 |
1986 | # Verify result contains expected fields
1987 | assert result['id'] == 'wfl-12345'
1988 | assert result['name'] == 'test-workflow'
1989 | assert result.get('description') is None
1990 |
1991 |
1992 | @pytest.mark.asyncio
1993 | async def test_create_workflow_version_s3_uri_with_static_storage():
1994 | """Test workflow version creation with S3 URI and STATIC storage."""
1995 | # Mock response data
1996 | mock_response = {
1997 | 'id': 'wfl-12345',
1998 | 'arn': 'arn:aws:omics:us-east-1:123456789012:workflow/wfl-12345',
1999 | 'status': 'ACTIVE',
2000 | 'name': 'test-workflow',
2001 | 'versionName': 'v2.0',
2002 | }
2003 |
2004 | # Mock context and client
2005 | mock_ctx = AsyncMock()
2006 | mock_client = MagicMock()
2007 | mock_client.create_workflow_version.return_value = mock_response
2008 |
2009 | with patch(
2010 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
2011 | return_value=mock_client,
2012 | ):
2013 | result = await create_workflow_version(
2014 | mock_ctx,
2015 | workflow_id='wfl-12345',
2016 | version_name='v2.0',
2017 | definition_zip_base64=None,
2018 | description=None,
2019 | parameter_template=None,
2020 | storage_type='STATIC',
2021 | storage_capacity=100,
2022 | container_registry_map=None,
2023 | container_registry_map_uri=None,
2024 | definition_uri='s3://my-bucket/workflow-definition-v2.zip',
2025 | )
2026 |
2027 | # Verify client was called with STATIC storage parameters
2028 | mock_client.create_workflow_version.assert_called_once_with(
2029 | workflowId='wfl-12345',
2030 | versionName='v2.0',
2031 | definitionUri='s3://my-bucket/workflow-definition-v2.zip',
2032 | storageType='STATIC',
2033 | storageCapacity=100,
2034 | )
2035 |
2036 | # Verify result contains expected fields
2037 | assert result['id'] == 'wfl-12345'
2038 | assert result['versionName'] == 'v2.0'
2039 |
2040 |
2041 | @pytest.mark.asyncio
2042 | async def test_list_workflow_versions_botocore_error():
2043 | """Test handling of BotoCoreError when listing workflow versions."""
2044 | # Mock context and client
2045 | mock_ctx = AsyncMock()
2046 | mock_client = MagicMock()
2047 | mock_client.list_workflow_versions.side_effect = botocore.exceptions.BotoCoreError()
2048 |
2049 | with patch(
2050 | 'awslabs.aws_healthomics_mcp_server.tools.workflow_management.get_omics_client',
2051 | return_value=mock_client,
2052 | ):
2053 | # Call the function and expect it to raise an exception
2054 | with pytest.raises(botocore.exceptions.BotoCoreError):
2055 | await list_workflow_versions(mock_ctx, workflow_id='wfl-12345')
2056 |
2057 | # Verify error was reported to context
2058 | mock_ctx.error.assert_called_once()
2059 | assert (
2060 | 'AWS error listing workflow versions for workflow wfl-12345'
2061 | in mock_ctx.error.call_args[0][0]
2062 | )
2063 |
```