This is page 520 of 542. 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.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-appsignals-mcp-server.md
│   │   │   ├── cloudwatch-mcp-server.md
│   │   │   ├── code-doc-gen-mcp-server.md
│   │   │   ├── core-mcp-server.md
│   │   │   ├── cost-explorer-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
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.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
│   │   │   ├── 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_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.py
│   │   │       ├── server.py
│   │   │       ├── tools
│   │   │       │   ├── __init__.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
│   │   │           └── validation_utils.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── docs
│   │   │   └── workflow_linting.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_aws_utils.py
│   │   │   ├── test_consts.py
│   │   │   ├── test_helper_tools.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_run_analysis.py
│   │   │   ├── test_s3_utils.py
│   │   │   ├── test_server.py
│   │   │   ├── test_troubleshooting.py
│   │   │   ├── test_workflow_analysis.py
│   │   │   ├── test_workflow_execution.py
│   │   │   ├── test_workflow_linting.py
│   │   │   ├── test_workflow_management.py
│   │   │   └── test_workflow_tools.py
│   │   ├── 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.py
│   │   │       ├── prompts
│   │   │       │   ├── __init__.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_data.py
│   │   │       │   ├── sitewise_gateways.py
│   │   │       │   └── sitewise_metadata_transfer.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
│   │   │   ├── test_client.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   ├── test_sitewise_access.py
│   │   │   ├── test_sitewise_asset_models.py
│   │   │   ├── test_sitewise_assets.py
│   │   │   ├── test_sitewise_data.py
│   │   │   ├── test_sitewise_gateways.py
│   │   │   ├── test_sitewise_metadata_transfer.py
│   │   │   └── test_validation.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-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
│   │   │       ├── 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_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
│   │   │       │   ├── data
│   │   │       │   │   └── metric_metadata.json
│   │   │       │   ├── 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_metrics_error_handling.py
│   │   │   │   ├── test_metrics_models.py
│   │   │   │   ├── test_metrics_server.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
│   ├── 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
│   │   │       ├── 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_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
└── VIBE_CODING_TIPS_TRICKS.md
```
# Files
--------------------------------------------------------------------------------
/src/well-architected-security-mcp-server/awslabs/well_architected_security_mcp_server/util/security_services.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 | """Utility functions for checking AWS security services and retrieving findings."""
  16 | 
  17 | import datetime
  18 | import json
  19 | from typing import Any, Dict, List, Optional
  20 | 
  21 | import boto3
  22 | from botocore.config import Config
  23 | from mcp.server.fastmcp import Context
  24 | 
  25 | from awslabs.well_architected_security_mcp_server import __version__
  26 | 
  27 | # User agent configuration for AWS API calls
  28 | USER_AGENT_CONFIG = Config(
  29 |     user_agent_extra=f"awslabs/mcp/well-architected-security-mcp-server/{__version__}"
  30 | )
  31 | 
  32 | 
  33 | async def get_analyzer_findings_count(
  34 |     analyzer_arn: str, analyzer_client: Any, ctx: Context
  35 | ) -> str:
  36 |     """Get the number of findings for an IAM Access Analyzer.
  37 | 
  38 |     Args:
  39 |         analyzer_arn: ARN of the IAM Access Analyzer
  40 |         analyzer_client: boto3 client for Access Analyzer
  41 |         ctx: MCP context for error reporting
  42 | 
  43 |     Returns:
  44 |         Count of findings as string, or "Unknown" if there was an error
  45 |     """
  46 |     try:
  47 |         response = analyzer_client.list_findings(analyzerArn=analyzer_arn)
  48 |         return str(len(response.get("findings", [])))
  49 |     except Exception as e:
  50 |         await ctx.warning(f"Error getting findings count: {e}")
  51 |         return "Unknown"
  52 | 
  53 | 
  54 | async def check_access_analyzer(region: str, session: boto3.Session, ctx: Context) -> Dict:
  55 |     """Check if IAM Access Analyzer is enabled in the specified region.
  56 | 
  57 |     Args:
  58 |         region: AWS region to check
  59 |         session: boto3 Session for AWS API calls
  60 |         ctx: MCP context for error reporting
  61 | 
  62 |     Returns:
  63 |         Dictionary with status information about IAM Access Analyzer
  64 |     """
  65 |     try:
  66 |         analyzer_client = session.client(
  67 |             "accessanalyzer", region_name=region, config=USER_AGENT_CONFIG
  68 |         )
  69 |         response = analyzer_client.list_analyzers()
  70 | 
  71 |         # Extract analyzers - verify the field exists to prevent KeyError
  72 |         flag = True
  73 |         if "analyzers" not in response:
  74 |             flag = False
  75 |         elif len(response["analyzers"]) == 0:
  76 |             flag = False
  77 | 
  78 |         if not flag:
  79 |             return {
  80 |                 "enabled": False,
  81 |                 "analyzers": [],
  82 |                 "debug_info": {"raw_response": response},
  83 |                 "setup_instructions": """
  84 |                 # IAM Access Analyzer Setup Instructions
  85 | 
  86 |                 IAM Access Analyzer is not enabled in this region. To enable it:
  87 | 
  88 |                 1. Open the IAM console: https://console.aws.amazon.com/iam/
  89 |                 2. Choose Access analyzer
  90 |                 3. Choose Create analyzer
  91 |                 4. Enter a name for the analyzer
  92 |                 5. Choose the type of analyzer (account or organization)
  93 |                 6. Choose Create analyzer
  94 | 
  95 |                 This is strongly recommended before proceeding with the security review.
  96 | 
  97 |                 Learn more: https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html
  98 |                 """,
  99 |                 "message": "IAM Access Analyzer is not enabled in this region.",
 100 |             }
 101 | 
 102 |         analyzers = response.get("analyzers", [])
 103 | 
 104 |         # Check if any of the analyzers are active
 105 |         active_analyzers = [a for a in analyzers if a.get("status") == "ACTIVE"]
 106 | 
 107 |         # Access Analyzer is enabled if there's at least one analyzer, even if not all are ACTIVE
 108 |         analyzer_details = []
 109 |         for analyzer in analyzers:
 110 |             analyzer_arn = analyzer.get("arn")
 111 |             if analyzer_arn:
 112 |                 try:
 113 |                     findings_count = await get_analyzer_findings_count(
 114 |                         analyzer_arn, analyzer_client, ctx
 115 |                     )
 116 | 
 117 |                 except Exception:
 118 |                     findings_count = "Error"
 119 |             else:
 120 |                 findings_count = "Unknown (No ARN)"
 121 | 
 122 |             analyzer_details.append(
 123 |                 {
 124 |                     "name": analyzer.get("name"),
 125 |                     "type": analyzer.get("type"),
 126 |                     "status": analyzer.get("status"),
 127 |                     "created_at": str(analyzer.get("createdAt")),
 128 |                     "findings_count": findings_count,
 129 |                 }
 130 |             )
 131 | 
 132 |         # Consider IAM Access Analyzer enabled if there's at least one analyzer, even if not all are ACTIVE
 133 |         return {
 134 |             "enabled": True,
 135 |             "analyzers": analyzer_details,
 136 |             "message": f"IAM Access Analyzer is enabled with {len(analyzers)} analyzer(s) ({len(active_analyzers)} active).",
 137 |         }
 138 |     except Exception as e:
 139 |         await ctx.error(f"Error checking IAM Access Analyzer status: {e}")
 140 |         return {
 141 |             "enabled": False,
 142 |             "error": str(e),
 143 |             "message": "Error checking IAM Access Analyzer status.",
 144 |         }
 145 | 
 146 | 
 147 | async def check_security_hub(region: str, session: boto3.Session, ctx: Context) -> Dict:
 148 |     """Check if AWS Security Hub is enabled in the specified region.
 149 | 
 150 |     Args:
 151 |         region: AWS region to check
 152 |         session: boto3 Session for AWS API calls
 153 |         ctx: MCP context for error reporting
 154 | 
 155 |     Returns:
 156 |         Dictionary with status information about AWS Security Hub
 157 |     """
 158 |     try:
 159 |         # Create Security Hub client
 160 |         securityhub_client = session.client(
 161 |             "securityhub", region_name=region, config=USER_AGENT_CONFIG
 162 |         )
 163 | 
 164 |         try:
 165 |             # Check if Security Hub is enabled
 166 |             hub_response = securityhub_client.describe_hub()
 167 | 
 168 |             # Security Hub is enabled, get enabled standards
 169 |             try:
 170 |                 standards_response = securityhub_client.get_enabled_standards()
 171 |                 standards = standards_response.get("StandardsSubscriptions", [])
 172 | 
 173 |                 # Safely process standards with better error handling
 174 |                 processed_standards = []
 175 |                 for standard in standards:
 176 |                     try:
 177 |                         standard_name = standard.get("StandardsArn", "").split("/")[-1]
 178 |                         standard_status = standard.get("StandardsStatus", "UNKNOWN")
 179 | 
 180 |                         # Handle the nested structure carefully
 181 |                         enabled_at = ""
 182 |                         if "StandardsSubscriptionArn" in standard:
 183 |                             # Sometimes EnabledAt is in the root or might not exist
 184 |                             enabled_at = str(standard.get("EnabledAt", ""))
 185 | 
 186 |                         processed_standards.append(
 187 |                             {
 188 |                                 "name": standard_name,
 189 |                                 "status": standard_status,
 190 |                                 "enabled_at": enabled_at,
 191 |                             }
 192 |                         )
 193 |                     except Exception:
 194 |                         pass
 195 | 
 196 |                 return {
 197 |                     "enabled": True,
 198 |                     "standards": processed_standards,
 199 |                     "message": f"Security Hub is enabled with {len(standards)} standards.",
 200 |                     "debug_info": {
 201 |                         "hub_arn": hub_response.get("HubArn", "Unknown"),
 202 |                         "standards_count": len(standards),
 203 |                     },
 204 |                 }
 205 |             except Exception as std_ex:
 206 |                 # Security Hub is enabled but we couldn't get standards
 207 |                 return {
 208 |                     "enabled": True,
 209 |                     "standards": [],
 210 |                     "message": "Security Hub is enabled but there was an error retrieving standards.",
 211 |                     "debug_info": {
 212 |                         "hub_arn": hub_response.get("HubArn", "Unknown"),
 213 |                         "error_getting_standards": str(std_ex),
 214 |                     },
 215 |                 }
 216 | 
 217 |         except securityhub_client.exceptions.InvalidAccessException:
 218 |             # Security Hub is not enabled
 219 |             return {
 220 |                 "enabled": False,
 221 |                 "standards": [],
 222 |                 "setup_instructions": """
 223 |                 # AWS Security Hub Setup Instructions
 224 |                 AWS Security Hub is not enabled in this region. To enable it:
 225 |                 https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html
 226 |                 """,
 227 |                 "message": "AWS Security Hub is not enabled in this region.",
 228 |             }
 229 |         except securityhub_client.exceptions.ResourceNotFoundException:
 230 |             # Hub not found - not enabled
 231 |             return {
 232 |                 "enabled": False,
 233 |                 "standards": [],
 234 |                 "setup_instructions": """
 235 |                 # AWS Security Hub Setup Instructions
 236 | 
 237 |                 AWS Security Hub is not enabled in this region. To enable it:
 238 | 
 239 |                 1. Open the Security Hub console: https://console.aws.amazon.com/securityhub/
 240 |                 2. Choose Go to Security Hub
 241 |                 3. Configure your security standards
 242 |                 4. Choose Enable Security Hub
 243 | 
 244 |                 This is strongly recommended for maintaining security best practices.
 245 | 
 246 |                 Learn more: https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html
 247 |                 """,
 248 |                 "message": "AWS Security Hub is not enabled in this region.",
 249 |             }
 250 |     except Exception as e:
 251 |         return {
 252 |             "enabled": False,
 253 |             "error": str(e),
 254 |             "message": "Error checking Security Hub status.",
 255 |             "debug_info": {"exception": str(e), "exception_type": type(e).__name__},
 256 |         }
 257 | 
 258 | 
 259 | async def check_guard_duty(region: str, session: boto3.Session, ctx: Context) -> Dict:
 260 |     """Check if Amazon GuardDuty is enabled in the specified region.
 261 | 
 262 |     Args:
 263 |         region: AWS region to check
 264 |         session: boto3 Session for AWS API calls
 265 |         ctx: MCP context for error reporting
 266 | 
 267 |     Returns:
 268 |         Dictionary with status information about Amazon GuardDuty
 269 |     """
 270 |     try:
 271 |         # Create GuardDuty client
 272 |         guardduty_client = session.client(
 273 |             "guardduty", region_name=region, config=USER_AGENT_CONFIG
 274 |         )
 275 | 
 276 |         # List detectors
 277 |         detector_response = guardduty_client.list_detectors()
 278 |         detector_ids = detector_response.get("DetectorIds", [])
 279 | 
 280 |         if not detector_ids:
 281 |             # GuardDuty is not enabled
 282 |             return {
 283 |                 "enabled": False,
 284 |                 "detector_details": {},
 285 |                 "setup_instructions": """
 286 |                 # Amazon GuardDuty Setup Instructions
 287 | 
 288 |                 Amazon GuardDuty is not enabled in this region. To enable it:
 289 | 
 290 |                 1. Open the GuardDuty console: https://console.aws.amazon.com/guardduty/
 291 |                 2. Choose Get Started
 292 |                 3. Choose Enable GuardDuty
 293 | 
 294 |                 This is strongly recommended for detecting threats to your AWS environment.
 295 | 
 296 |                 Learn more: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_settingup.html
 297 |                 """,
 298 |                 "message": "Amazon GuardDuty is not enabled in this region.",
 299 |             }
 300 | 
 301 |         # GuardDuty is enabled, get detector details
 302 |         detector_id = detector_ids[0]  # Use the first detector
 303 |         detector_details = guardduty_client.get_detector(DetectorId=detector_id)
 304 | 
 305 |         return {
 306 |             "enabled": True,
 307 |             "detector_details": {
 308 |                 "id": detector_id,
 309 |                 "status": "ENABLED",
 310 |                 "finding_publishing_frequency": detector_details.get("FindingPublishingFrequency"),
 311 |                 "data_sources": detector_details.get("DataSources"),
 312 |                 "features": detector_details.get("Features", []),
 313 |             },
 314 |             "message": "Amazon GuardDuty is enabled and active.",
 315 |         }
 316 |     except Exception as e:
 317 |         await ctx.error(f"Error checking GuardDuty status: {e}")
 318 |         return {"enabled": False, "error": str(e), "message": "Error checking GuardDuty status."}
 319 | 
 320 | 
 321 | async def check_inspector(region: str, session: boto3.Session, ctx: Context) -> Dict:
 322 |     """Check if Amazon Inspector is enabled in the specified region.
 323 | 
 324 |     Args:
 325 |         region: AWS region to check
 326 |         session: boto3 Session for AWS API calls
 327 |         ctx: MCP context for error reporting
 328 | 
 329 |     Returns:
 330 |         Dictionary with status information about Amazon Inspector
 331 |     """
 332 |     try:
 333 |         # Create Inspector client (using inspector2)
 334 |         inspector_client = session.client(
 335 |             "inspector2", region_name=region, config=USER_AGENT_CONFIG
 336 |         )
 337 | 
 338 |         try:
 339 |             # Get Inspector status
 340 |             try:
 341 |                 # First try using get_status API
 342 |                 status_response = inspector_client.get_status()
 343 |                 print(
 344 |                     f"[DEBUG:Inspector] get_status() successful, raw response: {status_response}"
 345 |                 )
 346 | 
 347 |                 # If we can call get_status successfully, Inspector2 is enabled
 348 |                 # Now we need to determine which scan types are enabled
 349 | 
 350 |                 # The service exists and is enabled at this point, since get_status worked
 351 |                 is_enabled = True
 352 | 
 353 |                 # Attempt to extract status from different possible response structures
 354 |                 status = {}
 355 | 
 356 |                 # Check all possible paths where status might be located
 357 |                 if isinstance(status_response, dict):
 358 |                     # Direct status fields in response root
 359 |                     for scan_type in ["EC2", "ECR", "LAMBDA", "ec2", "ecr", "lambda"]:
 360 |                         # Try all possible field name patterns for each scan type
 361 |                         for field_pattern in [
 362 |                             f"{scan_type}Status",
 363 |                             f"{scan_type.lower()}Status",
 364 |                             f"{scan_type}_status",
 365 |                             f"{scan_type.lower()}_status",
 366 |                             scan_type,
 367 |                             scan_type.lower(),
 368 |                         ]:
 369 |                             if field_pattern in status_response:
 370 |                                 status[field_pattern] = status_response[field_pattern]
 371 | 
 372 |                     # Try the 'status' nested object too
 373 |                     if "status" in status_response and isinstance(status_response["status"], dict):
 374 |                         for key, value in status_response["status"].items():
 375 |                             # Avoid duplicates if we've already found this info
 376 |                             if key not in status:
 377 |                                 status[key] = value
 378 | 
 379 |                 print(f"[DEBUG:Inspector] Extracted status fields: {status}")
 380 | 
 381 |                 # Check for enabled scan types
 382 |                 scan_types = ["EC2", "ECR", "LAMBDA"]
 383 |                 enabled_scans = []
 384 | 
 385 |                 for scan_type in scan_types:
 386 |                     found_enabled = False
 387 |                     # Check all possible status keys for this scan type
 388 |                     for status_key in [
 389 |                         f"{scan_type}Status",
 390 |                         f"{scan_type.lower()}Status",
 391 |                         f"{scan_type}_status",
 392 |                         f"{scan_type.lower()}_status",
 393 |                         scan_type,
 394 |                         scan_type.lower(),
 395 |                     ]:
 396 |                         status_value = None
 397 | 
 398 |                         # Try direct key in status dictionary
 399 |                         if status_key in status:
 400 |                             status_value = status[status_key]
 401 |                             print(
 402 |                                 f"[DEBUG:Inspector] Found status for {scan_type} via key {status_key}: {status_value}"
 403 |                             )
 404 | 
 405 |                         # Check if the status value indicates "enabled"
 406 |                         if status_value and (
 407 |                             (isinstance(status_value, str) and status_value.upper() == "ENABLED")
 408 |                             or (isinstance(status_value, bool) and status_value is True)
 409 |                         ):
 410 |                             enabled_scans.append(scan_type)
 411 |                             found_enabled = True
 412 |                             print(f"[DEBUG:Inspector] {scan_type} scan type is ENABLED")
 413 |                             break
 414 | 
 415 |                     if not found_enabled:
 416 |                         # If we haven't found an "enabled" status for this scan type, try one more approach
 417 |                         # Looking for any key that contains the scan type name and has "enabled" value
 418 |                         for status_key, status_value in status.items():
 419 |                             if (
 420 |                                 scan_type.lower() in status_key.lower()
 421 |                                 and isinstance(status_value, str)
 422 |                                 and "enable" in status_value.lower()
 423 |                             ):
 424 |                                 enabled_scans.append(scan_type)
 425 |                                 print(
 426 |                                     f"[DEBUG:Inspector] {scan_type} scan type is potentially enabled via fuzzy match"
 427 |                                 )
 428 |                                 break
 429 | 
 430 |                 print(f"[DEBUG:Inspector] Final enabled scan types: {enabled_scans}")
 431 | 
 432 |                 # Build the scan status dictionary
 433 |                 scan_status = {}
 434 |                 for scan_type in scan_types:
 435 |                     scan_found = False
 436 |                     scan_status_key = f"{scan_type.lower()}_status"
 437 | 
 438 |                     # Look for this scan type in the status dictionary
 439 |                     for status_key, status_value in status.items():
 440 |                         if scan_type.lower() in status_key.lower():
 441 |                             scan_status[scan_status_key] = status_value
 442 |                             scan_found = True
 443 |                             break
 444 | 
 445 |                     # If no matching key found, indicate unknown
 446 |                     if not scan_found:
 447 |                         scan_status[scan_status_key] = "UNKNOWN"
 448 | 
 449 |                 # By this point, if we successfully called get_status, the service itself is enabled
 450 |                 # Even if no scan types are explicitly shown as enabled
 451 |                 return {
 452 |                     "enabled": is_enabled,
 453 |                     "scan_status": scan_status,
 454 |                     "message": f"Amazon Inspector is enabled with the following scan types: {', '.join(enabled_scans) if enabled_scans else 'unknown'}",
 455 |                 }
 456 | 
 457 |             except Exception as status_error:
 458 |                 # log the error but continue with the alternative checks
 459 |                 print(f"[DEBUG:Inspector] get_status() error: {status_error}")
 460 |                 await ctx.warning(f"Error calling Inspector2 get_status(): {status_error}")
 461 | 
 462 |             # If get_status failed or didn't find scan types, try another approach
 463 |             # Try calling batch_get_account_status which may give different information
 464 |             try:
 465 |                 account_status = inspector_client.batch_get_account_status()
 466 | 
 467 |                 # If we get here, the service is enabled
 468 |                 if "accounts" in account_status and account_status["accounts"]:
 469 |                     account_info = account_status["accounts"][0]
 470 |                     resource_status = account_info.get("resourceStatus", {})
 471 | 
 472 |                     # Check which resources are enabled
 473 |                     ec2_enabled = resource_status.get("ec2", {}).get("status") == "ENABLED"
 474 |                     ecr_enabled = resource_status.get("ecr", {}).get("status") == "ENABLED"
 475 |                     lambda_enabled = resource_status.get("lambda", {}).get("status") == "ENABLED"
 476 | 
 477 |                     enabled_scans = []
 478 |                     if ec2_enabled:
 479 |                         enabled_scans.append("EC2")
 480 |                     if ecr_enabled:
 481 |                         enabled_scans.append("ECR")
 482 |                     if lambda_enabled:
 483 |                         enabled_scans.append("LAMBDA")
 484 | 
 485 |                     print(
 486 |                         f"[DEBUG:Inspector] From batch_get_account_status, enabled scans: {enabled_scans}"
 487 |                     )
 488 | 
 489 |                     # If we successfully called batch_get_account_status, treat Inspector as enabled
 490 |                     return {
 491 |                         "enabled": True,
 492 |                         "scan_status": {
 493 |                             "ec2_status": "ENABLED" if ec2_enabled else "DISABLED",
 494 |                             "ecr_status": "ENABLED" if ecr_enabled else "DISABLED",
 495 |                             "lambda_status": "ENABLED" if lambda_enabled else "DISABLED",
 496 |                         },
 497 |                         "message": f"Amazon Inspector is enabled with the following scan types: {', '.join(enabled_scans) if enabled_scans else 'none'}",
 498 |                     }
 499 |             except Exception as account_error:
 500 |                 print(f"[DEBUG:Inspector] batch_get_account_status() error: {account_error}")
 501 | 
 502 |             # As a last resort, try listing findings
 503 |             # If this works, it means Inspector is enabled
 504 |             try:
 505 |                 # Try listing a small number of findings just to test API access
 506 |                 findings_response = inspector_client.list_findings(maxResults=1)
 507 |                 flag = False
 508 |                 if findings_response:
 509 |                     flag = True
 510 |                 # If we can call list_findings, Inspector is definitely enabled
 511 |                 return {
 512 |                     "enabled": flag,
 513 |                     "scan_status": {
 514 |                         "ec2_status": "UNKNOWN",
 515 |                         "ecr_status": "UNKNOWN",
 516 |                         "lambda_status": "UNKNOWN",
 517 |                     },
 518 |                     "message": "Amazon Inspector is enabled, but specific scan types could not be determined.",
 519 |                 }
 520 |             except Exception as findings_error:
 521 |                 print(f"[DEBUG:Inspector] list_findings() error: {findings_error}")
 522 | 
 523 |             # If we get here, we've tried multiple methods but can't confirm Inspector is enabled
 524 |             print("[DEBUG:Inspector] All detection methods failed, treating as not enabled")
 525 |             return {
 526 |                 "enabled": False,
 527 |                 "scan_status": {
 528 |                     "ec2_status": "UNKNOWN",
 529 |                     "ecr_status": "UNKNOWN",
 530 |                     "lambda_status": "UNKNOWN",
 531 |                 },
 532 |                 "setup_instructions": """
 533 |                 # Amazon Inspector Setup Instructions
 534 | 
 535 |                 Amazon Inspector may not be fully enabled in this region. To enable it:
 536 | 
 537 |                 1. Open the Inspector console: https://console.aws.amazon.com/inspector/
 538 |                 2. Choose Settings
 539 |                 3. Enable the scan types you need (EC2, ECR, Lambda)
 540 | 
 541 |                 This is strongly recommended for identifying vulnerabilities in your workloads.
 542 | 
 543 |                 Learn more: https://docs.aws.amazon.com/inspector/latest/user/enabling-disable-scanning-account.html
 544 |                 """,
 545 |                 "message": "Amazon Inspector status could not be determined. Multiple detection methods failed.",
 546 |             }
 547 |         except inspector_client.exceptions.AccessDeniedException:
 548 |             # Inspector is not enabled or permissions issue
 549 |             return {
 550 |                 "enabled": False,
 551 |                 "setup_instructions": """
 552 |                 # Amazon Inspector Setup Instructions
 553 |                 Amazon Inspector is not enabled in this region. To enable it:
 554 |                 1. Open the Inspector console: https://console.aws.amazon.com/inspector/
 555 |                 2. Choose Get started
 556 |                 3. Choose Enable Amazon Inspector
 557 |                 4. Select the scan types to enable
 558 |                 """,
 559 |                 "message": "Amazon Inspector is not enabled in this region.",
 560 |             }
 561 |     except Exception as e:
 562 |         await ctx.error(f"Error checking Inspector status: {e}")
 563 |         return {"enabled": False, "error": str(e), "message": "Error checking Inspector status."}
 564 | 
 565 | 
 566 | # New functions to get findings from security services
 567 | 
 568 | 
 569 | async def get_guardduty_findings(
 570 |     region: str,
 571 |     session: boto3.Session,
 572 |     ctx: Context,
 573 |     max_findings: int = 100,
 574 |     filter_criteria: Optional[Dict] = None,
 575 | ) -> Dict:
 576 |     """Get findings from Amazon GuardDuty in the specified region.
 577 | 
 578 |     Args:
 579 |         region: AWS region to get findings from
 580 |         session: boto3 Session for AWS API calls
 581 |         ctx: MCP context for error reporting
 582 |         max_findings: Maximum number of findings to return (default: 100)
 583 |         filter_criteria: Optional filter criteria for findings
 584 | 
 585 |     Returns:
 586 |         Dictionary containing GuardDuty findings
 587 |     """
 588 |     try:
 589 |         # First check if GuardDuty is enabled
 590 |         print(f"[DEBUG:GuardDuty] Checking if GuardDuty is enabled in {region}")
 591 |         guardduty_status = await check_guard_duty(region, session, ctx)
 592 |         if not guardduty_status.get("enabled", False):
 593 |             print(f"[DEBUG:GuardDuty] GuardDuty is not enabled in {region}")
 594 |             return {
 595 |                 "enabled": False,
 596 |                 "message": "Amazon GuardDuty is not enabled in this region",
 597 |                 "findings": [],
 598 |                 "debug_info": "GuardDuty is not enabled, no findings retrieved",
 599 |             }
 600 | 
 601 |         # Get detector ID
 602 |         print("[DEBUG:GuardDuty] GuardDuty is enabled, retrieving detector ID")
 603 |         detector_id = guardduty_status.get("detector_details", {}).get("id")
 604 |         if not detector_id:
 605 |             print("[DEBUG:GuardDuty] ERROR: No GuardDuty detector ID found")
 606 |             await ctx.error("No GuardDuty detector ID found")
 607 |             return {
 608 |                 "enabled": True,
 609 |                 "error": "No GuardDuty detector ID found",
 610 |                 "findings": [],
 611 |                 "debug_info": "GuardDuty is enabled but no detector ID was found",
 612 |             }
 613 | 
 614 |         print(f"[DEBUG:GuardDuty] Using detector ID: {detector_id}")
 615 | 
 616 |         # Create GuardDuty client
 617 |         guardduty_client = session.client(
 618 |             "guardduty", region_name=region, config=USER_AGENT_CONFIG
 619 |         )
 620 | 
 621 |         # Set up default finding criteria if none provided
 622 |         if filter_criteria is None:
 623 |             print("[DEBUG:GuardDuty] No filter criteria provided, creating default criteria")
 624 |             # By default, get findings from the last 30 days with high or medium severity
 625 |             # Calculate timestamp in milliseconds (GuardDuty expects integer timestamp)
 626 |             thirty_days_ago = int(
 627 |                 (datetime.datetime.now() - datetime.timedelta(days=30)).timestamp() * 1000
 628 |             )
 629 | 
 630 |             filter_criteria = {
 631 |                 "Criterion": {
 632 |                     "severity": {
 633 |                         "Eq": ["7", "5", "8"]  # High (7), Medium (5), and Critical (8) findings
 634 |                     },
 635 |                     "updatedAt": {"GreaterThanOrEqual": thirty_days_ago},
 636 |                 }
 637 |             }
 638 |             print(
 639 |                 f"[DEBUG:GuardDuty] Created default filter criteria with timestamp: {thirty_days_ago} ({datetime.datetime.fromtimestamp(thirty_days_ago / 1000).isoformat()})"
 640 |             )
 641 |         else:
 642 |             print(
 643 |                 f"[DEBUG:GuardDuty] Using provided filter criteria: {json.dumps(filter_criteria)}"
 644 |             )
 645 | 
 646 |         # List findings with the filter criteria
 647 |         print(f"[DEBUG:GuardDuty] Calling list_findings with max results: {max_findings}")
 648 |         findings_response = guardduty_client.list_findings(
 649 |             DetectorId=detector_id, FindingCriteria=filter_criteria, MaxResults=max_findings
 650 |         )
 651 | 
 652 |         finding_ids = findings_response.get("FindingIds", [])
 653 |         print(f"[DEBUG:GuardDuty] Retrieved {len(finding_ids)} finding IDs")
 654 | 
 655 |         if not finding_ids:
 656 |             print("[DEBUG:GuardDuty] No findings match the filter criteria")
 657 |             return {
 658 |                 "enabled": True,
 659 |                 "message": "No GuardDuty findings match the filter criteria",
 660 |                 "findings": [],
 661 |                 "debug_info": "GuardDuty query returned no findings matching the criteria",
 662 |             }
 663 | 
 664 |         # Get finding details
 665 |         print(f"[DEBUG:GuardDuty] Retrieving details for {len(finding_ids)} findings")
 666 |         findings_details = guardduty_client.get_findings(
 667 |             DetectorId=detector_id, FindingIds=finding_ids
 668 |         )
 669 | 
 670 |         # Process findings to clean up non-serializable objects (like datetime)
 671 |         findings = []
 672 |         raw_findings_count = len(findings_details.get("Findings", []))
 673 |         print(
 674 |             f"[DEBUG:GuardDuty] Processing {raw_findings_count} findings from get_findings response"
 675 |         )
 676 | 
 677 |         for finding in findings_details.get("Findings", []):
 678 |             # Convert datetime objects to strings
 679 |             finding = _clean_datetime_objects(finding)
 680 |             findings.append(finding)
 681 | 
 682 |         print(f"[DEBUG:GuardDuty] Successfully processed {len(findings)} findings")
 683 | 
 684 |         # Generate summary
 685 |         summary = _summarize_guardduty_findings(findings)
 686 |         print(f"[DEBUG:GuardDuty] Generated summary with {summary['total_count']} findings")
 687 |         print(
 688 |             f"[DEBUG:GuardDuty] Severity breakdown: High={summary['severity_counts']['high']}, Medium={summary['severity_counts']['medium']}, Low={summary['severity_counts']['low']}"
 689 |         )
 690 | 
 691 |         return {
 692 |             "enabled": True,
 693 |             "message": f"Retrieved {len(findings)} GuardDuty findings",
 694 |             "findings": findings,
 695 |             "summary": summary,
 696 |             "debug_info": {
 697 |                 "detector_id": detector_id,
 698 |                 "finding_ids_retrieved": len(finding_ids),
 699 |                 "findings_details_retrieved": raw_findings_count,
 700 |                 "findings_processed": len(findings),
 701 |                 "filter_criteria": filter_criteria,
 702 |             },
 703 |         }
 704 |     except Exception as e:
 705 |         await ctx.error(f"Error getting GuardDuty findings: {e}")
 706 |         return {
 707 |             "enabled": True,
 708 |             "error": str(e),
 709 |             "message": "Error getting GuardDuty findings",
 710 |             "findings": [],
 711 |         }
 712 | 
 713 | 
 714 | async def get_securityhub_findings(
 715 |     region: str,
 716 |     session: boto3.Session,
 717 |     ctx: Context,
 718 |     max_findings: int = 100,
 719 |     filter_criteria: Optional[Dict] = None,
 720 | ) -> Dict:
 721 |     """Get findings from AWS Security Hub in the specified region.
 722 | 
 723 |     Args:
 724 |         region: AWS region to get findings from
 725 |         session: boto3 Session for AWS API calls
 726 |         ctx: MCP context for error reporting
 727 |         max_findings: Maximum number of findings to return (default: 100)
 728 |         filter_criteria: Optional filter criteria for findings
 729 | 
 730 |     Returns:
 731 |         Dictionary containing Security Hub findings
 732 |     """
 733 |     try:
 734 |         # First check if Security Hub is enabled
 735 |         securityhub_status = await check_security_hub(region, session, ctx)
 736 |         if not securityhub_status.get("enabled", False):
 737 |             return {
 738 |                 "enabled": False,
 739 |                 "message": "AWS Security Hub is not enabled in this region",
 740 |                 "findings": [],
 741 |             }
 742 | 
 743 |         # Create Security Hub client
 744 |         securityhub_client = session.client(
 745 |             "securityhub", region_name=region, config=USER_AGENT_CONFIG
 746 |         )
 747 | 
 748 |         # Set up default finding criteria if none provided
 749 |         if filter_criteria is None:
 750 |             # By default, get active findings from the last 30 days with high severity
 751 |             filter_criteria = {
 752 |                 "RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}],
 753 |                 "WorkflowStatus": [{"Comparison": "EQUALS", "Value": "NEW"}],
 754 |                 "UpdatedAt": [
 755 |                     {
 756 |                         "Start": (datetime.datetime.now() - datetime.timedelta(days=30)).strftime(
 757 |                             "%Y-%m-%dT%H:%M:%S.%fZ"
 758 |                         ),
 759 |                         "End": datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
 760 |                     }
 761 |                 ],
 762 |                 "SeverityLabel": [
 763 |                     {"Comparison": "EQUALS", "Value": "HIGH"},
 764 |                     {"Comparison": "EQUALS", "Value": "CRITICAL"},
 765 |                 ],
 766 |             }
 767 | 
 768 |         # Get findings with the filter criteria
 769 |         findings_response = securityhub_client.get_findings(
 770 |             Filters=filter_criteria, MaxResults=max_findings
 771 |         )
 772 | 
 773 |         findings = findings_response.get("Findings", [])
 774 | 
 775 |         if not findings:
 776 |             return {
 777 |                 "enabled": True,
 778 |                 "message": "No Security Hub findings match the filter criteria",
 779 |                 "findings": [],
 780 |             }
 781 | 
 782 |         # Process findings to clean up non-serializable objects (like datetime)
 783 |         processed_findings = []
 784 |         for finding in findings:
 785 |             # Convert datetime objects to strings
 786 |             finding = _clean_datetime_objects(finding)
 787 |             processed_findings.append(finding)
 788 | 
 789 |         return {
 790 |             "enabled": True,
 791 |             "message": f"Retrieved {len(processed_findings)} Security Hub findings",
 792 |             "findings": processed_findings,
 793 |             "summary": _summarize_securityhub_findings(processed_findings),
 794 |         }
 795 |     except Exception as e:
 796 |         await ctx.error(f"Error getting Security Hub findings: {e}")
 797 |         return {
 798 |             "enabled": True,
 799 |             "error": str(e),
 800 |             "message": "Error getting Security Hub findings",
 801 |             "findings": [],
 802 |         }
 803 | 
 804 | 
 805 | async def get_inspector_findings(
 806 |     region: str,
 807 |     session: boto3.Session,
 808 |     ctx: Context,
 809 |     max_findings: int = 100,
 810 |     filter_criteria: Optional[Dict] = None,
 811 | ) -> Dict:
 812 |     """Get findings from Amazon Inspector in the specified region.
 813 | 
 814 |     Args:
 815 |         region: AWS region to get findings from
 816 |         session: boto3 Session for AWS API calls
 817 |         ctx: MCP context for error reporting
 818 |         max_findings: Maximum number of findings to return (default: 100)
 819 |         filter_criteria: Optional filter criteria for findings
 820 | 
 821 |     Returns:
 822 |         Dictionary containing Inspector findings
 823 |     """
 824 |     try:
 825 |         # First check if Inspector is enabled
 826 |         inspector_status = await check_inspector(region, session, ctx)
 827 |         if not inspector_status.get("enabled", False):
 828 |             return {
 829 |                 "enabled": False,
 830 |                 "message": "Amazon Inspector is not enabled in this region",
 831 |                 "findings": [],
 832 |             }
 833 | 
 834 |         # Create Inspector client
 835 |         inspector_client = session.client(
 836 |             "inspector2", region_name=region, config=USER_AGENT_CONFIG
 837 |         )
 838 | 
 839 |         # Set up default finding criteria if none provided
 840 |         if filter_criteria is None:
 841 |             # By default, get findings with high or critical severity
 842 |             filter_criteria = {
 843 |                 "severities": [
 844 |                     {"comparison": "EQUALS", "value": "HIGH"},
 845 |                     {"comparison": "EQUALS", "value": "CRITICAL"},
 846 |                 ],
 847 |                 "findingStatus": [{"comparison": "EQUALS", "value": "ACTIVE"}],
 848 |             }
 849 | 
 850 |         # List findings with the filter criteria
 851 |         findings_response = inspector_client.list_findings(
 852 |             filterCriteria=filter_criteria, maxResults=max_findings
 853 |         )
 854 | 
 855 |         findings = findings_response.get("findings", [])
 856 | 
 857 |         if not findings:
 858 |             return {
 859 |                 "enabled": True,
 860 |                 "message": "No Inspector findings match the filter criteria",
 861 |                 "findings": [],
 862 |             }
 863 | 
 864 |         # Process findings to clean up non-serializable objects (like datetime)
 865 |         processed_findings = []
 866 |         for finding in findings:
 867 |             # Convert datetime objects to strings
 868 |             finding = _clean_datetime_objects(finding)
 869 |             processed_findings.append(finding)
 870 | 
 871 |         return {
 872 |             "enabled": True,
 873 |             "message": f"Retrieved {len(processed_findings)} Inspector findings",
 874 |             "findings": processed_findings,
 875 |             "summary": _summarize_inspector_findings(processed_findings),
 876 |         }
 877 |     except Exception as e:
 878 |         await ctx.error(f"Error getting Inspector findings: {e}")
 879 |         return {
 880 |             "enabled": True,
 881 |             "error": str(e),
 882 |             "message": "Error getting Inspector findings",
 883 |             "findings": [],
 884 |         }
 885 | 
 886 | 
 887 | async def get_access_analyzer_findings(
 888 |     region: str, session: boto3.Session, ctx: Context, analyzer_arn: Optional[str] = None
 889 | ) -> Dict:
 890 |     """Get findings from IAM Access Analyzer in the specified region.
 891 | 
 892 |     Args:
 893 |         region: AWS region to get findings from
 894 |         session: boto3 Session for AWS API calls
 895 |         ctx: MCP context for error reporting
 896 |         analyzer_arn: Optional ARN of a specific analyzer to get findings from
 897 | 
 898 |     Returns:
 899 |         Dictionary containing IAM Access Analyzer findings
 900 |     """
 901 |     try:
 902 |         # First check if Access Analyzer is enabled
 903 |         analyzer_status = await check_access_analyzer(region, session, ctx)
 904 |         if not analyzer_status.get("enabled", False):
 905 |             return {
 906 |                 "enabled": False,
 907 |                 "message": "IAM Access Analyzer is not enabled in this region",
 908 |                 "findings": [],
 909 |             }
 910 | 
 911 |         # Create Access Analyzer client
 912 |         analyzer_client = session.client(
 913 |             "accessanalyzer", region_name=region, config=USER_AGENT_CONFIG
 914 |         )
 915 | 
 916 |         analyzers = analyzer_status.get("analyzers", [])
 917 |         if not analyzers:
 918 |             return {
 919 |                 "enabled": True,
 920 |                 "message": "No IAM Access Analyzer analyzers found in this region",
 921 |                 "findings": [],
 922 |             }
 923 | 
 924 |         all_findings = []
 925 | 
 926 |         # If analyzer_arn is provided, only get findings for that analyzer
 927 |         if analyzer_arn:
 928 |             analyzers = [a for a in analyzers if a.get("arn") == analyzer_arn]
 929 | 
 930 |         # Get findings for each analyzer
 931 |         for analyzer in analyzers:
 932 |             analyzer_arn = analyzer.get("arn")
 933 |             if not analyzer_arn:
 934 |                 continue
 935 | 
 936 |             findings_response = analyzer_client.list_findings(
 937 |                 analyzerArn=analyzer_arn, maxResults=100
 938 |             )
 939 | 
 940 |             finding_ids = findings_response.get("findings", [])
 941 | 
 942 |             # Get details for each finding
 943 |             for finding_id in finding_ids:
 944 |                 finding_details = analyzer_client.get_finding(
 945 |                     analyzerArn=analyzer_arn, id=finding_id
 946 |                 )
 947 | 
 948 |                 # Clean up non-serializable objects
 949 |                 finding_details = _clean_datetime_objects(finding_details)
 950 |                 all_findings.append(finding_details)
 951 | 
 952 |         if not all_findings:
 953 |             return {
 954 |                 "enabled": True,
 955 |                 "message": "No IAM Access Analyzer findings found",
 956 |                 "findings": [],
 957 |             }
 958 | 
 959 |         return {
 960 |             "enabled": True,
 961 |             "message": f"Retrieved {len(all_findings)} IAM Access Analyzer findings",
 962 |             "findings": all_findings,
 963 |             "summary": _summarize_access_analyzer_findings(all_findings),
 964 |         }
 965 |     except Exception as e:
 966 |         await ctx.error(f"Error getting IAM Access Analyzer findings: {e}")
 967 |         return {
 968 |             "enabled": True,
 969 |             "error": str(e),
 970 |             "message": "Error getting IAM Access Analyzer findings",
 971 |             "findings": [],
 972 |         }
 973 | 
 974 | 
 975 | # Helper functions for processing findings
 976 | 
 977 | 
 978 | def _clean_datetime_objects(obj: Any) -> Any:
 979 |     """Convert datetime objects in a nested dictionary to ISO format strings.
 980 | 
 981 |     Args:
 982 |         obj: Object that may contain datetime objects
 983 | 
 984 |     Returns:
 985 |         Object with datetime objects converted to strings
 986 |     """
 987 |     if isinstance(obj, datetime.datetime):
 988 |         return obj.isoformat()
 989 |     elif isinstance(obj, list):
 990 |         return [_clean_datetime_objects(item) for item in obj]
 991 |     elif isinstance(obj, dict):
 992 |         return {k: _clean_datetime_objects(v) for k, v in obj.items()}
 993 |     else:
 994 |         return obj
 995 | 
 996 | 
 997 | def _summarize_guardduty_findings(findings: List[Dict]) -> Dict:
 998 |     """Generate a summary of GuardDuty findings.
 999 | 
1000 |     Args:
1001 |         findings: List of GuardDuty finding dictionaries
1002 | 
1003 |     Returns:
1004 |         Dictionary with summary information
1005 |     """
1006 |     summary = {
1007 |         "total_count": len(findings),
1008 |         "severity_counts": {"high": 0, "medium": 0, "low": 0},
1009 |         "type_counts": {},
1010 |         "resource_counts": {},
1011 |     }
1012 | 
1013 |     for finding in findings:
1014 |         # Count by severity
1015 |         severity = finding.get("Severity", 0)
1016 |         if severity >= 7:
1017 |             summary["severity_counts"]["high"] += 1
1018 |         elif severity >= 4:
1019 |             summary["severity_counts"]["medium"] += 1
1020 |         else:
1021 |             summary["severity_counts"]["low"] += 1
1022 | 
1023 |         # Count by finding type
1024 |         finding_type = finding.get("Type", "unknown")
1025 |         if finding_type in summary["type_counts"]:
1026 |             summary["type_counts"][finding_type] += 1
1027 |         else:
1028 |             summary["type_counts"][finding_type] = 1
1029 | 
1030 |         # Count by resource type
1031 |         resource_type = finding.get("Resource", {}).get("ResourceType", "unknown")
1032 |         if resource_type in summary["resource_counts"]:
1033 |             summary["resource_counts"][resource_type] += 1
1034 |         else:
1035 |             summary["resource_counts"][resource_type] = 1
1036 | 
1037 |     return summary
1038 | 
1039 | 
1040 | def _summarize_securityhub_findings(findings: List[Dict]) -> Dict:
1041 |     """Generate a summary of Security Hub findings.
1042 | 
1043 |     Args:
1044 |         findings: List of Security Hub finding dictionaries
1045 | 
1046 |     Returns:
1047 |         Dictionary with summary information
1048 |     """
1049 |     summary = {
1050 |         "total_count": len(findings),
1051 |         "severity_counts": {"critical": 0, "high": 0, "medium": 0, "low": 0},
1052 |         "standard_counts": {},
1053 |         "resource_type_counts": {},
1054 |     }
1055 | 
1056 |     for finding in findings:
1057 |         # Count by severity
1058 |         severity = finding.get("Severity", {}).get("Label", "MEDIUM").upper()
1059 |         if severity == "CRITICAL":
1060 |             summary["severity_counts"]["critical"] += 1
1061 |         elif severity == "HIGH":
1062 |             summary["severity_counts"]["high"] += 1
1063 |         elif severity == "MEDIUM":
1064 |             summary["severity_counts"]["medium"] += 1
1065 |         else:
1066 |             summary["severity_counts"]["low"] += 1
1067 | 
1068 |         # Count by compliance standard
1069 |         product_name = finding.get("ProductName", "unknown")
1070 |         if product_name in summary["standard_counts"]:
1071 |             summary["standard_counts"][product_name] += 1
1072 |         else:
1073 |             summary["standard_counts"][product_name] = 1
1074 | 
1075 |         # Count by resource type
1076 |         resources = finding.get("Resources", [])
1077 |         for resource in resources:
1078 |             resource_type = resource.get("Type", "unknown")
1079 |             if resource_type in summary["resource_type_counts"]:
1080 |                 summary["resource_type_counts"][resource_type] += 1
1081 |             else:
1082 |                 summary["resource_type_counts"][resource_type] = 1
1083 | 
1084 |     return summary
1085 | 
1086 | 
1087 | def _summarize_inspector_findings(findings: List[Dict]) -> Dict:
1088 |     """Generate a summary of Inspector findings.
1089 | 
1090 |     Args:
1091 |         findings: List of Inspector finding dictionaries
1092 | 
1093 |     Returns:
1094 |         Dictionary with summary information
1095 |     """
1096 |     summary = {
1097 |         "total_count": len(findings),
1098 |         "severity_counts": {"critical": 0, "high": 0, "medium": 0, "low": 0},
1099 |         "type_counts": {},
1100 |         "resource_type_counts": {},
1101 |     }
1102 | 
1103 |     for finding in findings:
1104 |         # Count by severity
1105 |         severity = finding.get("severity", "MEDIUM")
1106 |         if severity == "CRITICAL":
1107 |             summary["severity_counts"]["critical"] += 1
1108 |         elif severity == "HIGH":
1109 |             summary["severity_counts"]["high"] += 1
1110 |         elif severity == "MEDIUM":
1111 |             summary["severity_counts"]["medium"] += 1
1112 |         else:
1113 |             summary["severity_counts"]["low"] += 1
1114 | 
1115 |         # Count by finding type
1116 |         finding_type = finding.get("type", "unknown")
1117 |         if finding_type in summary["type_counts"]:
1118 |             summary["type_counts"][finding_type] += 1
1119 |         else:
1120 |             summary["type_counts"][finding_type] = 1
1121 | 
1122 |         # Count by resource type
1123 |         resource_type = finding.get("resourceType", "unknown")
1124 |         if resource_type in summary["resource_type_counts"]:
1125 |             summary["resource_type_counts"][resource_type] += 1
1126 |         else:
1127 |             summary["resource_type_counts"][resource_type] = 1
1128 | 
1129 |     return summary
1130 | 
1131 | 
1132 | def _summarize_access_analyzer_findings(findings: List[Dict]) -> Dict:
1133 |     """Generate a summary of IAM Access Analyzer findings.
1134 | 
1135 |     Args:
1136 |         findings: List of IAM Access Analyzer finding dictionaries
1137 | 
1138 |     Returns:
1139 |         Dictionary with summary information
1140 |     """
1141 |     summary = {"total_count": len(findings), "resource_type_counts": {}, "action_counts": {}}
1142 | 
1143 |     for finding in findings:
1144 |         # Count by resource type
1145 |         resource_type = finding.get("resourceType", "unknown")
1146 |         if resource_type in summary["resource_type_counts"]:
1147 |             summary["resource_type_counts"][resource_type] += 1
1148 |         else:
1149 |             summary["resource_type_counts"][resource_type] = 1
1150 | 
1151 |         # Count by action
1152 |         actions = finding.get("action", [])
1153 |         for action in actions:
1154 |             if action in summary["action_counts"]:
1155 |                 summary["action_counts"][action] += 1
1156 |             else:
1157 |                 summary["action_counts"][action] = 1
1158 | 
1159 |     return summary
1160 | 
1161 | 
1162 | async def check_trusted_advisor(region: str, session: boto3.Session, ctx: Context) -> Dict:
1163 |     """Check if AWS Trusted Advisor is accessible in the account.
1164 | 
1165 |     Args:
1166 |         region: AWS region to check (Trusted Advisor is a global service, but API calls must be made to us-east-1)
1167 |         session: boto3 Session for AWS API calls
1168 |         ctx: MCP context for error reporting
1169 | 
1170 |     Returns:
1171 |         Dictionary with status information about AWS Trusted Advisor
1172 | 
1173 |     Note:
1174 |         Full Trusted Advisor functionality requires Business or Enterprise Support plan.
1175 |     """
1176 |     try:
1177 |         print("[DEBUG:TrustedAdvisor] Starting Trusted Advisor check")
1178 | 
1179 |         # Trusted Advisor API is only available in us-east-1
1180 |         support_client = session.client(
1181 |             "support", region_name="us-east-1", config=USER_AGENT_CONFIG
1182 |         )
1183 | 
1184 |         try:
1185 |             # Try to describe Trusted Advisor checks to see if we have access
1186 |             print("[DEBUG:TrustedAdvisor] Calling describe_trusted_advisor_checks API")
1187 |             checks_response = support_client.describe_trusted_advisor_checks(language="en")
1188 | 
1189 |             # If we get here, we have access to Trusted Advisor
1190 |             checks = checks_response.get("checks", [])
1191 |             print(
1192 |                 f"[DEBUG:TrustedAdvisor] Successfully retrieved {len(checks)} Trusted Advisor checks"
1193 |             )
1194 | 
1195 |             # Count checks by category
1196 |             category_counts = {}
1197 |             for check in checks:
1198 |                 category = check.get("category", "unknown")
1199 |                 if category in category_counts:
1200 |                     category_counts[category] += 1
1201 |                 else:
1202 |                     category_counts[category] = 1
1203 | 
1204 |             # Count security checks specifically
1205 |             security_checks = [check for check in checks if check.get("category") == "security"]
1206 |             print(f"[DEBUG:TrustedAdvisor] Found {len(security_checks)} security-related checks")
1207 | 
1208 |             # Determine support tier based on number of checks
1209 |             # Basic support typically has 7 core checks, Business/Enterprise has 100+
1210 |             support_tier = "Basic" if len(checks) < 20 else "Business/Enterprise"
1211 | 
1212 |             return {
1213 |                 "enabled": True,
1214 |                 "support_tier": support_tier,
1215 |                 "total_checks": len(checks),
1216 |                 "security_checks": len(security_checks),
1217 |                 "category_counts": category_counts,
1218 |                 "message": f"AWS Trusted Advisor is accessible with {support_tier} Support ({len(checks)} checks available, {len(security_checks)} security checks).",
1219 |             }
1220 | 
1221 |         except support_client.exceptions.SubscriptionRequiredException:
1222 |             # This exception means Trusted Advisor is not available with the current support plan
1223 |             return {
1224 |                 "enabled": False,
1225 |                 "support_tier": "Basic",
1226 |                 "setup_instructions": """
1227 |                 # AWS Trusted Advisor Full Access Requirements
1228 | 
1229 |                 Full access to AWS Trusted Advisor requires Business or Enterprise Support plan.
1230 | 
1231 |                 With your current support plan, you have limited access to Trusted Advisor.
1232 |                 To get full access to all Trusted Advisor checks:
1233 | 
1234 |                 1. Open the AWS Support Center Console: https://console.aws.amazon.com/support/
1235 |                 2. Choose Support Center
1236 |                 3. Choose Compare or change your Support plan
1237 |                 4. Upgrade to Business or Enterprise Support
1238 | 
1239 |                 Learn more: https://aws.amazon.com/premiumsupport/
1240 |                 """,
1241 |                 "message": "Full AWS Trusted Advisor functionality requires Business or Enterprise Support plan.",
1242 |             }
1243 | 
1244 |     except Exception as e:
1245 |         await ctx.error(f"Error checking Trusted Advisor status: {e}")
1246 |         return {
1247 |             "enabled": False,
1248 |             "error": str(e),
1249 |             "message": "Error checking Trusted Advisor status.",
1250 |         }
1251 | 
1252 | 
1253 | async def get_trusted_advisor_findings(
1254 |     region: str,
1255 |     session: boto3.Session,
1256 |     ctx: Context,
1257 |     max_findings: int = 100,
1258 |     status_filter: Optional[List[str]] = None,
1259 |     category_filter: Optional[str] = None,
1260 | ) -> Dict:
1261 |     """Retrieve check results from AWS Trusted Advisor.
1262 | 
1263 |     Args:
1264 |         region: AWS region (Trusted Advisor is global, but API calls must be made to us-east-1)
1265 |         session: boto3 Session for AWS API calls
1266 |         ctx: MCP context for error reporting
1267 |         max_findings: Maximum number of findings to return (default: 100)
1268 |         status_filter: Optional list of statuses to filter by (e.g., ['error', 'warning'])
1269 |         category_filter: Optional category to filter by (e.g., 'security')
1270 | 
1271 |     Returns:
1272 |         Dictionary containing Trusted Advisor check results
1273 |     """
1274 |     try:
1275 |         print("[DEBUG:TrustedAdvisor] Starting findings retrieval")
1276 | 
1277 |         # Set default status filter if not provided
1278 |         if status_filter is None:
1279 |             status_filter = ["error", "warning"]
1280 | 
1281 |         # First check if Trusted Advisor is accessible
1282 |         ta_status = await check_trusted_advisor(region, session, ctx)
1283 |         if not ta_status.get("enabled", False):
1284 |             print("[DEBUG:TrustedAdvisor] Trusted Advisor is not fully accessible")
1285 |             return {
1286 |                 "enabled": False,
1287 |                 "message": ta_status.get("message", "AWS Trusted Advisor is not accessible"),
1288 |                 "findings": [],
1289 |                 "support_tier": ta_status.get("support_tier", "Unknown"),
1290 |             }
1291 | 
1292 |         # Create Support client (Trusted Advisor API is only available in us-east-1)
1293 |         support_client = session.client(
1294 |             "support", region_name="us-east-1", config=USER_AGENT_CONFIG
1295 |         )
1296 | 
1297 |         # Get all available checks
1298 |         print("[DEBUG:TrustedAdvisor] Getting all available checks")
1299 |         checks_response = support_client.describe_trusted_advisor_checks(language="en")
1300 |         all_checks = checks_response.get("checks", [])
1301 | 
1302 |         # Filter checks by category if specified
1303 |         filtered_checks = all_checks
1304 |         if category_filter:
1305 |             filtered_checks = [
1306 |                 check
1307 |                 for check in all_checks
1308 |                 if check.get("category", "").lower() == category_filter.lower()
1309 |             ]
1310 |             print(
1311 |                 f"[DEBUG:TrustedAdvisor] Filtered to {len(filtered_checks)} {category_filter} checks"
1312 |             )
1313 | 
1314 |         # Limit the number of checks to process based on max_findings
1315 |         checks_to_process = filtered_checks[:max_findings]
1316 | 
1317 |         # Get check results
1318 |         findings = []
1319 |         for check in checks_to_process:
1320 |             check_id = check.get("id", "unknown")  # Initialize check_id outside try block
1321 |             try:
1322 |                 result = support_client.describe_trusted_advisor_check_result(
1323 |                     checkId=check_id, language="en"
1324 |                 )
1325 | 
1326 |                 # Extract the result
1327 |                 check_result = result.get("result", {})
1328 |                 status = check_result.get("status", "").lower()
1329 | 
1330 |                 # Skip checks that don't match the status filter
1331 |                 if status_filter and status not in status_filter:
1332 |                     continue
1333 | 
1334 |                 # Format the finding
1335 |                 finding = {
1336 |                     "check_id": check_id,
1337 |                     "name": check.get("name"),
1338 |                     "description": check.get("description"),
1339 |                     "category": check.get("category"),
1340 |                     "status": status,
1341 |                     "timestamp": check_result.get("timestamp"),
1342 |                     "resources_flagged": check_result.get("resourcesSummary", {}).get(
1343 |                         "resourcesFlagged", 0
1344 |                     ),
1345 |                     "resources_processed": check_result.get("resourcesSummary", {}).get(
1346 |                         "resourcesProcessed", 0
1347 |                     ),
1348 |                     "resources_suppressed": check_result.get("resourcesSummary", {}).get(
1349 |                         "resourcesSuppressed", 0
1350 |                     ),
1351 |                     "flagged_resources": [],
1352 |                 }
1353 | 
1354 |                 # Add flagged resources
1355 |                 flagged_resources = check_result.get("flaggedResources", [])
1356 |                 for resource in flagged_resources:
1357 |                     # Clean up the resource data
1358 |                     resource_data = _clean_datetime_objects(resource)
1359 |                     finding["flagged_resources"].append(resource_data)
1360 | 
1361 |                 findings.append(finding)
1362 |                 print(
1363 |                     f"[DEBUG:TrustedAdvisor] Added finding: {finding['name']} (status: {finding['status']}, resources: {finding['resources_flagged']})"
1364 |                 )
1365 | 
1366 |             except Exception as check_error:
1367 |                 await ctx.warning(
1368 |                     f"Error getting results for Trusted Advisor check {check_id}: {check_error}"
1369 |                 )
1370 | 
1371 |         # Generate summary
1372 |         summary = _summarize_trusted_advisor_findings(findings)
1373 | 
1374 |         return {
1375 |             "enabled": True,
1376 |             "message": f"Retrieved {len(findings)} Trusted Advisor findings",
1377 |             "findings": findings,
1378 |             "summary": summary,
1379 |             "support_tier": ta_status.get("support_tier", "Unknown"),
1380 |         }
1381 | 
1382 |     except Exception as e:
1383 |         await ctx.error(f"Error getting Trusted Advisor findings: {e}")
1384 |         return {
1385 |             "enabled": True,
1386 |             "error": str(e),
1387 |             "message": "Error getting Trusted Advisor findings",
1388 |             "findings": [],
1389 |         }
1390 | 
1391 | 
1392 | def _summarize_trusted_advisor_findings(findings: List[Dict]) -> Dict:
1393 |     """Generate a summary of Trusted Advisor findings.
1394 | 
1395 |     Args:
1396 |         findings: List of Trusted Advisor finding dictionaries
1397 | 
1398 |     Returns:
1399 |         Dictionary with summary information
1400 |     """
1401 |     summary = {
1402 |         "total_count": len(findings),
1403 |         "status_counts": {"error": 0, "warning": 0, "ok": 0, "not_available": 0},
1404 |         "category_counts": {},
1405 |         "resources_flagged": 0,
1406 |     }
1407 | 
1408 |     for finding in findings:
1409 |         # Count by status
1410 |         status = finding.get("status", "").lower()
1411 |         if status in summary["status_counts"]:
1412 |             summary["status_counts"][status] += 1
1413 |         else:
1414 |             summary["status_counts"]["not_available"] += 1
1415 | 
1416 |         # Count by category
1417 |         category = finding.get("category", "unknown")
1418 |         if category in summary["category_counts"]:
1419 |             summary["category_counts"][category] += 1
1420 |         else:
1421 |             summary["category_counts"][category] = 1
1422 | 
1423 |         # Count total flagged resources
1424 |         summary["resources_flagged"] += finding.get("resources_flagged", 0)
1425 | 
1426 |     return summary
1427 | 
1428 | 
1429 | async def check_macie(region: str, session: boto3.Session, ctx: Context) -> Dict:
1430 |     """Check if Amazon Macie is enabled in the specified region.
1431 | 
1432 |     Args:
1433 |         region: AWS region to check
1434 |         session: boto3 Session for AWS API calls
1435 |         ctx: MCP context for error reporting
1436 | 
1437 |     Returns:
1438 |         Dictionary with status information about Amazon Macie
1439 |     """
1440 |     try:
1441 |         print(f"[DEBUG:Macie] Starting Macie check for region: {region}")
1442 |         # Create Macie client
1443 |         macie_client = session.client("macie2", region_name=region, config=USER_AGENT_CONFIG)
1444 | 
1445 |         # Check if Macie is enabled
1446 |         try:
1447 |             print("[DEBUG:Macie] Calling get_macie_session() API")
1448 |             status = macie_client.get_macie_session()
1449 |             print(f"[DEBUG:Macie] get_macie_session() successful, status: {status.get('status')}")
1450 | 
1451 |             # If we get here without exception, Macie is enabled
1452 |             return {
1453 |                 "enabled": True,
1454 |                 "status": status.get("status"),
1455 |                 "created_at": str(status.get("createdAt")),
1456 |                 "service_role": status.get("serviceRole"),
1457 |                 "finding_publishing_frequency": status.get("findingPublishingFrequency"),
1458 |                 "message": "Amazon Macie is enabled in this region.",
1459 |             }
1460 |         except macie_client.exceptions.AccessDeniedException:
1461 |             return {
1462 |                 "enabled": False,
1463 |                 "setup_instructions": """
1464 |                 # Amazon Macie Setup Instructions
1465 | 
1466 |                 Amazon Macie is not enabled in this region. To enable it:
1467 | 
1468 |                 1. Open the Macie console: https://console.aws.amazon.com/macie/
1469 |                 2. Choose Get Started
1470 |                 3. Configure your settings and choose Enable Macie
1471 | 
1472 |                 This is recommended for discovering and protecting sensitive data in S3 buckets.
1473 | 
1474 |                 Learn more: https://docs.aws.amazon.com/macie/latest/user/getting-started.html
1475 |                 """,
1476 |                 "message": "Amazon Macie is not enabled in this region.",
1477 |             }
1478 |     except Exception as e:
1479 |         await ctx.error(f"Error checking Macie status: {e}")
1480 |         return {
1481 |             "enabled": False,
1482 |             "error": str(e),
1483 |             "message": "Error checking Macie status.",
1484 |             "debug_info": {"exception": str(e), "exception_type": type(e).__name__},
1485 |         }
1486 | 
1487 | 
1488 | async def get_macie_findings(
1489 |     region: str,
1490 |     session: boto3.Session,
1491 |     ctx: Context,
1492 |     max_findings: int = 100,
1493 |     filter_criteria: Optional[Dict] = None,
1494 | ) -> Dict:
1495 |     """Get findings from Amazon Macie in the specified region.
1496 | 
1497 |     Args:
1498 |         region: AWS region to get findings from
1499 |         session: boto3 Session for AWS API calls
1500 |         ctx: MCP context for error reporting
1501 |         max_findings: Maximum number of findings to return (default: 100)
1502 |         filter_criteria: Optional filter criteria for findings
1503 | 
1504 |     Returns:
1505 |         Dictionary containing Macie findings
1506 |     """
1507 |     try:
1508 |         print(f"[DEBUG:Macie] Starting findings retrieval for region: {region}")
1509 |         # First check if Macie is enabled
1510 |         macie_status = await check_macie(region, session, ctx)
1511 |         if not macie_status.get("enabled", False):
1512 |             print(f"[DEBUG:Macie] Macie is not enabled in {region}")
1513 |             return {
1514 |                 "enabled": False,
1515 |                 "message": "Amazon Macie is not enabled in this region",
1516 |                 "findings": [],
1517 |             }
1518 | 
1519 |         # Create Macie client
1520 |         macie_client = session.client("macie2", region_name=region, config=USER_AGENT_CONFIG)
1521 | 
1522 |         # Set up default finding criteria if none provided
1523 |         if filter_criteria is None:
1524 |             filter_criteria = {"criterion": {"severity.score": {"gt": 7}}}
1525 | 
1526 |         # List findings with the filter criteria
1527 |         findings_response = macie_client.list_findings(
1528 |             findingCriteria=filter_criteria, maxResults=max_findings
1529 |         )
1530 | 
1531 |         finding_ids = findings_response.get("findingIds", [])
1532 |         print(f"[DEBUG:Macie] Retrieved {len(finding_ids)} finding IDs")
1533 | 
1534 |         if not finding_ids:
1535 |             return {
1536 |                 "enabled": True,
1537 |                 "message": "No Macie findings match the filter criteria",
1538 |                 "findings": [],
1539 |             }
1540 | 
1541 |         # Get finding details
1542 |         print(f"[DEBUG:Macie] Retrieving details for {len(finding_ids)} findings")
1543 |         findings_details = macie_client.get_findings(findingIds=finding_ids)
1544 | 
1545 |         # Process findings to clean up non-serializable objects (like datetime)
1546 |         findings = []
1547 |         raw_findings_count = len(findings_details.get("findings", []))
1548 |         print(f"[DEBUG:Macie] Processing {raw_findings_count} findings from get_findings response")
1549 | 
1550 |         for finding in findings_details.get("findings", []):
1551 |             # Convert datetime objects to strings
1552 |             finding = _clean_datetime_objects(finding)
1553 |             findings.append(finding)
1554 | 
1555 |         print(f"[DEBUG:Macie] Successfully processed {len(findings)} findings")
1556 | 
1557 |         # Generate summary
1558 |         summary = _summarize_macie_findings(findings)
1559 |         print(f"[DEBUG:Macie] Generated summary with {summary['total_count']} findings")
1560 | 
1561 |         return {
1562 |             "enabled": True,
1563 |             "message": f"Retrieved {len(findings)} Macie findings",
1564 |             "findings": findings,
1565 |             "summary": summary,
1566 |         }
1567 |     except Exception as e:
1568 |         await ctx.error(f"Error getting Macie findings: {e}")
1569 |         return {
1570 |             "enabled": True,
1571 |             "error": str(e),
1572 |             "message": "Error getting Macie findings",
1573 |             "findings": [],
1574 |         }
1575 | 
1576 | 
1577 | def _summarize_macie_findings(findings: List[Dict]) -> Dict:
1578 |     """Generate a summary of Macie findings.
1579 | 
1580 |     Args:
1581 |         findings: List of Macie finding dictionaries
1582 | 
1583 |     Returns:
1584 |         Dictionary with summary information
1585 |     """
1586 |     summary = {
1587 |         "total_count": len(findings),
1588 |         "severity_counts": {"high": 0, "medium": 0, "low": 0},
1589 |         "type_counts": {},
1590 |         "bucket_counts": {},
1591 |     }
1592 | 
1593 |     for finding in findings:
1594 |         # Count by severity
1595 |         severity = finding.get("severity", {}).get("score", 0)
1596 |         if severity >= 7:
1597 |             summary["severity_counts"]["high"] += 1
1598 |         elif severity >= 4:
1599 |             summary["severity_counts"]["medium"] += 1
1600 |         else:
1601 |             summary["severity_counts"]["low"] += 1
1602 | 
1603 |         # Count by finding type
1604 |         finding_type = finding.get("type", "unknown")
1605 |         if finding_type in summary["type_counts"]:
1606 |             summary["type_counts"][finding_type] += 1
1607 |         else:
1608 |             summary["type_counts"][finding_type] = 1
1609 | 
1610 |         # Count by S3 bucket
1611 |         resource = finding.get("resourcesAffected", {}).get("s3Bucket", {})
1612 |         bucket_name = resource.get("name", "unknown")
1613 |         if bucket_name in summary["bucket_counts"]:
1614 |             summary["bucket_counts"][bucket_name] += 1
1615 |         else:
1616 |             summary["bucket_counts"][bucket_name] = 1
1617 | 
1618 |     return summary
1619 | 
```