#
tokens: 53531/50000 1/2497 files (page 548/575)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 548 of 575. 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
│   │   │       │   ├── computation_data_models.py
│   │   │       │   └── metadata_transfer_data_models.py
│   │   │       ├── prompts
│   │   │       │   ├── __init__.py
│   │   │       │   ├── anomaly_detection_workflow.py
│   │   │       │   ├── asset_hierarchy.py
│   │   │       │   ├── bulk_import_workflow.py
│   │   │       │   ├── data_exploration.py
│   │   │       │   └── data_ingestion.py
│   │   │       ├── server.py
│   │   │       ├── tool_metadata.py
│   │   │       ├── tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── sitewise_access.py
│   │   │       │   ├── sitewise_asset_models.py
│   │   │       │   ├── sitewise_assets.py
│   │   │       │   ├── sitewise_computation_models.py
│   │   │       │   ├── sitewise_data.py
│   │   │       │   ├── sitewise_executions.py
│   │   │       │   ├── sitewise_gateways.py
│   │   │       │   ├── sitewise_metadata_transfer.py
│   │   │       │   └── timestamp_tools.py
│   │   │       ├── validation_utils.py
│   │   │       └── validation.py
│   │   ├── CHANGELOG.md
│   │   ├── DEVELOPMENT.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   └── wind_farm_example.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_server.py
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── models
│   │   │   │   ├── test_computation_data_models.py
│   │   │   │   └── test_metadata_transfer_data_models.py
│   │   │   ├── test_client.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_server.py
│   │   │   ├── test_validation_utils.py
│   │   │   ├── test_validation.py
│   │   │   └── tools
│   │   │       ├── test_sitewise_access.py
│   │   │       ├── test_sitewise_asset_models.py
│   │   │       ├── test_sitewise_assets.py
│   │   │       ├── test_sitewise_computation_models.py
│   │   │       ├── test_sitewise_data.py
│   │   │       ├── test_sitewise_executions.py
│   │   │       ├── test_sitewise_gateways.py
│   │   │       ├── test_sitewise_metadata_transfer.py
│   │   │       └── test_timestamp_tools.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-knowledge-mcp-server
│   │   └── README.md
│   ├── aws-location-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_location_server
│   │   │       ├── __init__.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_server_integration.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-msk-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_msk_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── tools
│   │   │           ├── __init__.py
│   │   │           ├── common_functions
│   │   │           │   ├── __init__.py
│   │   │           │   ├── client_manager.py
│   │   │           │   └── common_functions.py
│   │   │           ├── logs_and_telemetry
│   │   │           │   ├── __init__.py
│   │   │           │   ├── cluster_metrics_tools.py
│   │   │           │   ├── list_customer_iam_access.py
│   │   │           │   └── metric_config.py
│   │   │           ├── mutate_cluster
│   │   │           │   ├── __init__.py
│   │   │           │   ├── batch_associate_scram_secret.py
│   │   │           │   ├── batch_disassociate_scram_secret.py
│   │   │           │   ├── create_cluster_v2.py
│   │   │           │   ├── put_cluster_policy.py
│   │   │           │   ├── reboot_broker.py
│   │   │           │   ├── update_broker_count.py
│   │   │           │   ├── update_broker_storage.py
│   │   │           │   ├── update_broker_type.py
│   │   │           │   ├── update_cluster_configuration.py
│   │   │           │   ├── update_monitoring.py
│   │   │           │   └── update_security.py
│   │   │           ├── mutate_config
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_configuration.py
│   │   │           │   ├── tag_resource.py
│   │   │           │   ├── untag_resource.py
│   │   │           │   └── update_configuration.py
│   │   │           ├── mutate_vpc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_vpc_connection.py
│   │   │           │   ├── delete_vpc_connection.py
│   │   │           │   └── reject_client_vpc_connection.py
│   │   │           ├── read_cluster
│   │   │           │   ├── __init__.py
│   │   │           │   ├── describe_cluster_operation.py
│   │   │           │   ├── describe_cluster.py
│   │   │           │   ├── get_bootstrap_brokers.py
│   │   │           │   ├── get_cluster_policy.py
│   │   │           │   ├── get_compatible_kafka_versions.py
│   │   │           │   ├── list_client_vpc_connections.py
│   │   │           │   ├── list_cluster_operations.py
│   │   │           │   ├── list_nodes.py
│   │   │           │   └── list_scram_secrets.py
│   │   │           ├── read_config
│   │   │           │   ├── __init__.py
│   │   │           │   ├── describe_configuration_revision.py
│   │   │           │   ├── describe_configuration.py
│   │   │           │   ├── list_configuration_revisions.py
│   │   │           │   └── list_tags_for_resource.py
│   │   │           ├── read_global
│   │   │           │   ├── __init__.py
│   │   │           │   ├── list_clusters.py
│   │   │           │   ├── list_configurations.py
│   │   │           │   ├── list_kafka_versions.py
│   │   │           │   └── list_vpc_connections.py
│   │   │           ├── read_vpc
│   │   │           │   ├── __init__.py
│   │   │           │   └── describe_vpc_connection.py
│   │   │           └── static_tools
│   │   │               ├── __init__.py
│   │   │               └── cluster_best_practices.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_client_manager.py
│   │   │   ├── test_cluster_metrics_tools.py
│   │   │   ├── test_common_functions.py
│   │   │   ├── test_create_cluster_v2.py
│   │   │   ├── test_create_configuration.py
│   │   │   ├── test_create_vpc_connection.py
│   │   │   ├── test_delete_vpc_connection.py
│   │   │   ├── test_describe_cluster_operation.py
│   │   │   ├── test_describe_cluster.py
│   │   │   ├── test_describe_configuration_revision.py
│   │   │   ├── test_describe_configuration.py
│   │   │   ├── test_describe_vpc_connection.py
│   │   │   ├── test_get_bootstrap_brokers.py
│   │   │   ├── test_get_cluster_policy.py
│   │   │   ├── test_get_compatible_kafka_versions.py
│   │   │   ├── test_init.py
│   │   │   ├── test_list_client_vpc_connections.py
│   │   │   ├── test_list_cluster_operations.py
│   │   │   ├── test_list_clusters.py
│   │   │   ├── test_list_configuration_revisions.py
│   │   │   ├── test_list_configurations.py
│   │   │   ├── test_list_customer_iam_access.py
│   │   │   ├── test_list_kafka_versions.py
│   │   │   ├── test_list_nodes.py
│   │   │   ├── test_list_scram_secrets.py
│   │   │   ├── test_list_tags_for_resource.py
│   │   │   ├── test_list_vpc_connections.py
│   │   │   ├── test_logs_and_telemetry.py
│   │   │   ├── test_main.py
│   │   │   ├── test_mutate_cluster_init.py
│   │   │   ├── test_mutate_cluster_success_cases.py
│   │   │   ├── test_mutate_cluster.py
│   │   │   ├── test_mutate_config_init.py
│   │   │   ├── test_mutate_vpc_init.py
│   │   │   ├── test_read_cluster_init_updated.py
│   │   │   ├── test_read_cluster_init.py
│   │   │   ├── test_read_config_init.py
│   │   │   ├── test_read_global_init.py
│   │   │   ├── test_read_vpc_init.py
│   │   │   ├── test_reject_client_vpc_connection.py
│   │   │   ├── test_server.py
│   │   │   ├── test_static_tools_init.py
│   │   │   ├── test_tag_resource.py
│   │   │   ├── test_tool_descriptions.py
│   │   │   ├── test_untag_resource.py
│   │   │   └── test_update_configuration.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-pricing-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_pricing_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── cdk_analyzer.py
│   │   │       ├── consts.py
│   │   │       ├── helpers.py
│   │   │       ├── models.py
│   │   │       ├── pricing_client.py
│   │   │       ├── pricing_transformer.py
│   │   │       ├── report_generator.py
│   │   │       ├── server.py
│   │   │       ├── static
│   │   │       │   ├── __init__.py
│   │   │       │   ├── COST_REPORT_TEMPLATE.md
│   │   │       │   └── patterns
│   │   │       │       ├── __init__.py
│   │   │       │       └── BEDROCK.md
│   │   │       └── terraform_analyzer.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_cdk_analyzer.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_pricing_client.py
│   │   │   ├── test_pricing_transformer.py
│   │   │   ├── test_report_generator.py
│   │   │   ├── test_server.py
│   │   │   └── test_terraform_analyzer.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-serverless-mcp-server
│   │   ├── .pre-commit.config.yaml
│   │   ├── .python-version
│   │   ├── .secrets.baseline
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_serverless_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── models.py
│   │   │       ├── resources
│   │   │       │   ├── __init__.py
│   │   │       │   ├── deployment_details.py
│   │   │       │   ├── deployment_list.py
│   │   │       │   ├── template_details.py
│   │   │       │   └── template_list.py
│   │   │       ├── server.py
│   │   │       ├── template
│   │   │       │   ├── __init__.py
│   │   │       │   ├── registry.py
│   │   │       │   ├── renderer.py
│   │   │       │   └── templates
│   │   │       │       ├── backend.j2
│   │   │       │       ├── frontend.j2
│   │   │       │       ├── fullstack.j2
│   │   │       │       └── README.md
│   │   │       ├── templates
│   │   │       │   ├── __init__.py
│   │   │       │   └── iam_policies.py
│   │   │       ├── tools
│   │   │       │   ├── common
│   │   │       │   │   └── base_tool.py
│   │   │       │   ├── esm
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── esm_diagnosis.py
│   │   │       │   │   ├── esm_guidance.py
│   │   │       │   │   ├── esm_recommend.py
│   │   │       │   │   └── secure_esm_guidance.py
│   │   │       │   ├── guidance
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── deploy_serverless_app_help.py
│   │   │       │   │   ├── get_iac_guidance.py
│   │   │       │   │   ├── get_lambda_event_schemas.py
│   │   │       │   │   ├── get_lambda_guidance.py
│   │   │       │   │   └── get_serverless_templates.py
│   │   │       │   ├── poller
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── esm_diagnosis.py
│   │   │       │   │   ├── esm_guidance.py
│   │   │       │   │   └── esm_recommend.py
│   │   │       │   ├── sam
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── sam_build.py
│   │   │       │   │   ├── sam_deploy.py
│   │   │       │   │   ├── sam_init.py
│   │   │       │   │   ├── sam_local_invoke.py
│   │   │       │   │   └── sam_logs.py
│   │   │       │   ├── schemas
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── describe_schema.py
│   │   │       │   │   ├── list_registries.py
│   │   │       │   │   └── search_schema.py
│   │   │       │   └── webapps
│   │   │       │       ├── __init__.py
│   │   │       │       ├── configure_domain.py
│   │   │       │       ├── deploy_webapp.py
│   │   │       │       ├── get_metrics.py
│   │   │       │       ├── update_webapp_frontend.py
│   │   │       │       ├── utils
│   │   │       │       │   ├── deploy_service.py
│   │   │       │       │   ├── frontend_uploader.py
│   │   │       │       │   └── startup_script_generator.py
│   │   │       │       └── webapp_deployment_help.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── aws_client_helper.py
│   │   │           ├── cloudformation.py
│   │   │           ├── const.py
│   │   │           ├── data_scrubber.py
│   │   │           ├── deployment_manager.py
│   │   │           ├── github.py
│   │   │           └── process.py
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_cloudformation.py
│   │   │   ├── test_configure_domain.py
│   │   │   ├── test_data_scrubber.py
│   │   │   ├── test_deploy_serverless_app_help.py
│   │   │   ├── test_deploy_service.py
│   │   │   ├── test_deploy_webapp.py
│   │   │   ├── test_deployment_details.py
│   │   │   ├── test_deployment_help.py
│   │   │   ├── test_deployment_list.py
│   │   │   ├── test_deployment_manager.py
│   │   │   ├── test_esm_diagnosis.py
│   │   │   ├── test_esm_guidance.py
│   │   │   ├── test_esm_recommend.py
│   │   │   ├── test_frontend_uploader.py
│   │   │   ├── test_get_iac_guidance.py
│   │   │   ├── test_get_lambda_event_schemas.py
│   │   │   ├── test_get_lambda_guidance.py
│   │   │   ├── test_get_metrics.py
│   │   │   ├── test_get_serverless_templates.py
│   │   │   ├── test_github.py
│   │   │   ├── test_iam_policies.py
│   │   │   ├── test_models.py
│   │   │   ├── test_process.py
│   │   │   ├── test_sam_build.py
│   │   │   ├── test_sam_deploy.py
│   │   │   ├── test_sam_init.py
│   │   │   ├── test_sam_local_invoke.py
│   │   │   ├── test_sam_logs.py
│   │   │   ├── test_schemas.py
│   │   │   ├── test_secure_esm_guidance.py
│   │   │   ├── test_server.py
│   │   │   ├── test_startup_script_generator.py
│   │   │   ├── test_template_details.py
│   │   │   ├── test_template_list.py
│   │   │   ├── test_template_registry.py
│   │   │   ├── test_template_renderer.py
│   │   │   └── test_update_webapp_frontend.py
│   │   └── uv.lock
│   ├── aws-support-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_support_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── client.py
│   │   │       ├── consts.py
│   │   │       ├── debug_helper.py
│   │   │       ├── errors.py
│   │   │       ├── formatters.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftests.py
│   │   │   ├── test_aws_support_mcp_server.py
│   │   │   └── test_models.py
│   │   └── uv.lock
│   ├── bedrock-kb-retrieval-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── bedrock_kb_retrieval_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── knowledgebases
│   │   │       │   ├── __init__.py
│   │   │       │   ├── clients.py
│   │   │       │   ├── discovery.py
│   │   │       │   └── retrieval.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_clients.py
│   │   │   ├── test_discovery.py
│   │   │   ├── test_env_config.py
│   │   │   ├── test_models.py
│   │   │   ├── test_retrieval.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── billing-cost-management-mcp-server
│   │   ├── __init__.py
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── billing_cost_management_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── models.py
│   │   │       ├── prompts
│   │   │       │   ├── __init__.py
│   │   │       │   ├── decorator.py
│   │   │       │   ├── graviton_migration.py
│   │   │       │   ├── README.md
│   │   │       │   ├── savings_plans.py
│   │   │       │   └── types.py
│   │   │       ├── server.py
│   │   │       ├── templates
│   │   │       │   └── recommendation_templates
│   │   │       │       ├── ebs_volume.template
│   │   │       │       ├── ec2_asg.template
│   │   │       │       ├── ec2_instance.template
│   │   │       │       ├── ecs_service.template
│   │   │       │       ├── idle.template
│   │   │       │       ├── lambda_function.template
│   │   │       │       ├── rds_database.template
│   │   │       │       ├── reserved_instances.template
│   │   │       │       └── savings_plans.template
│   │   │       ├── tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── aws_pricing_operations.py
│   │   │       │   ├── aws_pricing_tools.py
│   │   │       │   ├── bcm_pricing_calculator_tools.py
│   │   │       │   ├── budget_tools.py
│   │   │       │   ├── compute_optimizer_tools.py
│   │   │       │   ├── cost_anomaly_tools.py
│   │   │       │   ├── cost_comparison_tools.py
│   │   │       │   ├── cost_explorer_operations.py
│   │   │       │   ├── cost_explorer_tools.py
│   │   │       │   ├── cost_optimization_hub_helpers.py
│   │   │       │   ├── cost_optimization_hub_tools.py
│   │   │       │   ├── free_tier_usage_tools.py
│   │   │       │   ├── recommendation_details_tools.py
│   │   │       │   ├── ri_performance_tools.py
│   │   │       │   ├── sp_performance_tools.py
│   │   │       │   ├── storage_lens_tools.py
│   │   │       │   └── unified_sql_tools.py
│   │   │       └── utilities
│   │   │           ├── __init__.py
│   │   │           ├── aws_service_base.py
│   │   │           ├── constants.py
│   │   │           ├── logging_utils.py
│   │   │           └── sql_utils.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── prompts
│   │   │   │   ├── __init__.py
│   │   │   │   └── test_prompts.py
│   │   │   ├── README.md
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   ├── tools
│   │   │   │   ├── __init__.py
│   │   │   │   ├── fixtures.py
│   │   │   │   ├── test_aws_bcm_pricing_calculator_tools.py
│   │   │   │   ├── test_aws_pricing_tools.py
│   │   │   │   ├── test_budget_tools.py
│   │   │   │   ├── test_compute_optimizer_tools.py
│   │   │   │   ├── test_cost_anomaly_tools_enhanced.py
│   │   │   │   ├── test_cost_anomaly_tools.py
│   │   │   │   ├── test_cost_comparison_tools.py
│   │   │   │   ├── test_cost_explorer_operations.py
│   │   │   │   ├── test_cost_explorer_tools.py
│   │   │   │   ├── test_cost_optimization_hub_helpers.py
│   │   │   │   ├── test_cost_optimization_hub_tools.py
│   │   │   │   ├── test_free_tier_usage_tools_new.py
│   │   │   │   ├── test_recommendation_details_tools.py
│   │   │   │   ├── test_ri_performance_tools.py
│   │   │   │   ├── test_sp_performance_tools.py
│   │   │   │   ├── test_storage_lens_tools.py
│   │   │   │   └── test_unified_sql_tools.py
│   │   │   └── utilities
│   │   │       ├── test_aws_service_base.py
│   │   │       └── test_sql_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── ccapi-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── ccapi_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── cloud_control_utils.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── iac_generator.py
│   │   │       ├── impl
│   │   │       │   ├── __init__.py
│   │   │       │   ├── tools
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── explanation.py
│   │   │       │   │   ├── infrastructure_generation.py
│   │   │       │   │   ├── resource_operations.py
│   │   │       │   │   ├── security_scanning.py
│   │   │       │   │   └── session_management.py
│   │   │       │   └── utils
│   │   │       │       ├── __init__.py
│   │   │       │       └── validation.py
│   │   │       ├── infrastructure_generator.py
│   │   │       ├── models
│   │   │       │   ├── __init__.py
│   │   │       │   └── models.py
│   │   │       ├── schema_manager.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           └── __init__.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_aws_client.py
│   │   │   ├── test_checkov_install.py
│   │   │   ├── test_cloud_control_utils.py
│   │   │   ├── test_context.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_explanation.py
│   │   │   ├── test_iac_generator.py
│   │   │   ├── test_infrastructure_generation.py
│   │   │   ├── test_infrastructure_generator.py
│   │   │   ├── test_models.py
│   │   │   ├── test_resource_operations.py
│   │   │   ├── test_schema_manager.py
│   │   │   ├── test_security_scanning.py
│   │   │   ├── test_server.py
│   │   │   ├── test_session_management.py
│   │   │   └── test_validation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cdk-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cdk_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── core
│   │   │       │   ├── __init__.py
│   │   │       │   ├── resources.py
│   │   │       │   ├── search_utils.py
│   │   │       │   ├── server.py
│   │   │       │   └── tools.py
│   │   │       ├── data
│   │   │       │   ├── __init__.py
│   │   │       │   ├── cdk_nag_parser.py
│   │   │       │   ├── construct_descriptions.py
│   │   │       │   ├── genai_cdk_loader.py
│   │   │       │   ├── lambda_layer_parser.py
│   │   │       │   ├── lambda_powertools_loader.py
│   │   │       │   ├── schema_generator.py
│   │   │       │   └── solutions_constructs_parser.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           ├── __init__.py
│   │   │           ├── CDK_GENERAL_GUIDANCE.md
│   │   │           ├── CDK_NAG_GUIDANCE.md
│   │   │           └── lambda_powertools
│   │   │               ├── bedrock.md
│   │   │               ├── cdk.md
│   │   │               ├── dependencies.md
│   │   │               ├── index.md
│   │   │               ├── insights.md
│   │   │               ├── logging.md
│   │   │               ├── metrics.md
│   │   │               └── tracing.md
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── core
│   │   │   │   ├── test_resources_enhanced.py
│   │   │   │   ├── test_resources.py
│   │   │   │   ├── test_search_utils.py
│   │   │   │   ├── test_server.py
│   │   │   │   └── test_tools.py
│   │   │   └── data
│   │   │       ├── test_cdk_nag_parser.py
│   │   │       ├── test_genai_cdk_loader.py
│   │   │       ├── test_lambda_powertools_loader.py
│   │   │       ├── test_schema_generator.py
│   │   │       └── test_solutions_constructs_parser.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cfn-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cfn_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── cloud_control_utils.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── iac_generator.py
│   │   │       ├── schema_manager.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_aws_client.py
│   │   │   ├── test_cloud_control_utils.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_iac_generator.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_schema_manager.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudtrail-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudtrail_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── tools.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_tools.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudwatch-appsignals-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudwatch_appsignals_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── audit_presentation_utils.py
│   │   │       ├── audit_utils.py
│   │   │       ├── aws_clients.py
│   │   │       ├── canary_utils.py
│   │   │       ├── enablement_guides
│   │   │       │   └── templates
│   │   │       │       └── ec2
│   │   │       │           └── ec2-python-enablement.md
│   │   │       ├── enablement_tools.py
│   │   │       ├── server.py
│   │   │       ├── service_audit_utils.py
│   │   │       ├── service_tools.py
│   │   │       ├── sli_report_client.py
│   │   │       ├── slo_tools.py
│   │   │       ├── trace_tools.py
│   │   │       └── utils.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_audit_presentation_utils.py
│   │   │   ├── test_audit_utils.py
│   │   │   ├── test_aws_profile.py
│   │   │   ├── test_canary_utils.py
│   │   │   ├── test_enablement_tools.py
│   │   │   ├── test_initialization.py
│   │   │   ├── test_server_audit_functions.py
│   │   │   ├── test_server_audit_tools.py
│   │   │   ├── test_server.py
│   │   │   ├── test_service_audit_utils.py
│   │   │   ├── test_service_tools_operations.py
│   │   │   ├── test_sli_report_client.py
│   │   │   ├── test_slo_tools.py
│   │   │   └── test_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudwatch-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudwatch_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── cloudwatch_alarms
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── cloudwatch_logs
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── cloudwatch_metrics
│   │   │       │   ├── cloudformation_template_generator.py
│   │   │       │   ├── constants.py
│   │   │       │   ├── data
│   │   │       │   │   └── metric_metadata.json
│   │   │       │   ├── metric_analyzer.py
│   │   │       │   ├── metric_data_decomposer.py
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── common.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── cloudwatch_alarms
│   │   │   │   ├── test_active_alarms.py
│   │   │   │   ├── test_alarm_history_integration.py
│   │   │   │   ├── test_alarm_history.py
│   │   │   │   └── test_alarms_error_handling.py
│   │   │   ├── cloudwatch_logs
│   │   │   │   ├── test_logs_error_handling.py
│   │   │   │   ├── test_logs_models.py
│   │   │   │   └── test_logs_server.py
│   │   │   ├── cloudwatch_metrics
│   │   │   │   ├── test_analyze_metric.py
│   │   │   │   ├── test_cloudformation_template_generator.py
│   │   │   │   ├── test_decomposer_trend.py
│   │   │   │   ├── test_metric_analyzer.py
│   │   │   │   ├── test_metrics_error_handling.py
│   │   │   │   ├── test_metrics_models.py
│   │   │   │   ├── test_metrics_server.py
│   │   │   │   ├── test_seasonal_detector.py
│   │   │   │   ├── test_seasonality_enum.py
│   │   │   │   ├── test_utils.py
│   │   │   │   └── test_validation_error.py
│   │   │   ├── test_common_and_server.py
│   │   │   ├── test_init.py
│   │   │   └── test_main.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── code-doc-gen-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── code_doc_gen_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── doc_generator.py
│   │   │           ├── models.py
│   │   │           ├── repomix_manager.py
│   │   │           └── templates.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_doc_generator_edge_cases.py
│   │   │   ├── test_doc_generator.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_repomix_manager_scenarios.py
│   │   │   ├── test_repomix_manager.py
│   │   │   ├── test_repomix_statistics.py
│   │   │   ├── test_server_extended.py
│   │   │   ├── test_server.py
│   │   │   └── test_templates.py
│   │   └── uv.lock
│   ├── core-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── core_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           ├── __init__.py
│   │   │           └── PROMPT_UNDERSTANDING.md
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_response_types.py
│   │   │   ├── test_server.py
│   │   │   └── test_static.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cost-explorer-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cost_explorer_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── comparison_handler.py
│   │   │       ├── constants.py
│   │   │       ├── cost_usage_handler.py
│   │   │       ├── forecasting_handler.py
│   │   │       ├── helpers.py
│   │   │       ├── metadata_handler.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── utility_handler.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_comparison_handler.py
│   │   │   ├── test_cost_usage_handler.py
│   │   │   ├── test_forecasting_handler.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_metadata_handler.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_utility_handler.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── documentdb-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   └── documentdb_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── analytic_tools.py
│   │   │       ├── config.py
│   │   │       ├── connection_tools.py
│   │   │       ├── db_management_tools.py
│   │   │       ├── query_tools.py
│   │   │       ├── server.py
│   │   │       └── write_tools.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_analytic_tools.py
│   │   │   ├── test_connection_tools.py
│   │   │   ├── test_db_management_tools.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_query_tools.py
│   │   │   └── test_write_tools.py
│   │   └── uv.lock
│   ├── dynamodb-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── dynamodb_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common.py
│   │   │       ├── database_analysis_queries.py
│   │   │       ├── database_analyzers.py
│   │   │       ├── markdown_formatter.py
│   │   │       ├── prompts
│   │   │       │   └── dynamodb_architect.md
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── evals
│   │   │   │   ├── dynamic_evaluators.py
│   │   │   │   ├── evaluation_registry.py
│   │   │   │   ├── logging_config.py
│   │   │   │   ├── multiturn_evaluator.py
│   │   │   │   ├── README.md
│   │   │   │   ├── scenarios.py
│   │   │   │   └── test_dspy_evals.py
│   │   │   ├── test_dynamodb_server.py
│   │   │   ├── test_markdown_formatter.py
│   │   │   └── test_source_db_integration.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── ecs-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── ecs_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── api
│   │   │       │   ├── __init__.py
│   │   │       │   ├── containerize.py
│   │   │       │   ├── delete.py
│   │   │       │   ├── ecs_troubleshooting.py
│   │   │       │   ├── infrastructure.py
│   │   │       │   ├── resource_management.py
│   │   │       │   ├── status.py
│   │   │       │   └── troubleshooting_tools
│   │   │       │       ├── __init__.py
│   │   │       │       ├── detect_image_pull_failures.py
│   │   │       │       ├── fetch_cloudformation_status.py
│   │   │       │       ├── fetch_network_configuration.py
│   │   │       │       ├── fetch_service_events.py
│   │   │       │       ├── fetch_task_failures.py
│   │   │       │       ├── fetch_task_logs.py
│   │   │       │       ├── get_ecs_troubleshooting_guidance.py
│   │   │       │       └── utils.py
│   │   │       ├── main.py
│   │   │       ├── modules
│   │   │       │   ├── __init__.py
│   │   │       │   ├── aws_knowledge_proxy.py
│   │   │       │   ├── containerize.py
│   │   │       │   ├── delete.py
│   │   │       │   ├── deployment_status.py
│   │   │       │   ├── infrastructure.py
│   │   │       │   ├── resource_management.py
│   │   │       │   └── troubleshooting.py
│   │   │       ├── templates
│   │   │       │   ├── ecr_infrastructure.json
│   │   │       │   └── ecs_infrastructure.json
│   │   │       └── utils
│   │   │           ├── arn_parser.py
│   │   │           ├── aws.py
│   │   │           ├── config.py
│   │   │           ├── docker.py
│   │   │           ├── security.py
│   │   │           ├── templates.py
│   │   │           └── time_utils.py
│   │   ├── DEVELOPMENT.md
│   │   ├── pyproject.toml
│   │   ├── pyrightconfig.json
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── integ
│   │   │   │   └── mcp-inspector
│   │   │   │       ├── .gitignore
│   │   │   │       ├── README.md
│   │   │   │       ├── run-tests.sh
│   │   │   │       └── scenarios
│   │   │   │           ├── 01_comprehensive_troubleshooting
│   │   │   │           │   ├── 01_create.sh
│   │   │   │           │   ├── 02_validate.sh
│   │   │   │           │   ├── 03_cleanup.sh
│   │   │   │           │   ├── description.txt
│   │   │   │           │   └── utils
│   │   │   │           │       ├── mcp_helpers.sh
│   │   │   │           │       └── validation_helpers.sh
│   │   │   │           └── 02_test_knowledge_proxy_tools
│   │   │   │               ├── 01_create.sh
│   │   │   │               ├── 02_validate.sh
│   │   │   │               ├── 03_cleanup.sh
│   │   │   │               ├── description.txt
│   │   │   │               └── utils
│   │   │   │                   ├── knowledge_validation_helpers.sh
│   │   │   │                   └── mcp_knowledge_helpers.sh
│   │   │   ├── llm_testing
│   │   │   │   ├── invalid_cfn_template.yaml
│   │   │   │   ├── README.md
│   │   │   │   ├── run_tests.sh
│   │   │   │   ├── scenarios
│   │   │   │   │   ├── 01_cloudformation_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 02_service_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 03_task_exit_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 04_network_configuration_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 05_resource_constraint_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   └── 06_load_balancer_failure
│   │   │   │   │       ├── 01_create.sh
│   │   │   │   │       ├── 02_validate.sh
│   │   │   │   │       ├── 03_prompts.txt
│   │   │   │   │       ├── 05_cleanup.sh
│   │   │   │   │       └── description.txt
│   │   │   │   ├── SCRIPT_IMPROVEMENTS.md
│   │   │   │   └── utils
│   │   │   │       ├── aws_helpers.sh
│   │   │   │       └── evaluation_template.md
│   │   │   └── unit
│   │   │       ├── __init__.py
│   │   │       ├── api
│   │   │       │   ├── conftest.py
│   │   │       │   ├── test_delete_api.py
│   │   │       │   ├── test_ecs_troubleshooting.py
│   │   │       │   ├── test_resource_management_api.py
│   │   │       │   └── troubleshooting_tools
│   │   │       │       └── test_fetch_network_configuration.py
│   │   │       ├── conftest.py
│   │   │       ├── modules
│   │   │       │   ├── test_aws_knowledge_proxy.py
│   │   │       │   └── test_resource_management_module.py
│   │   │       ├── test_aws_role_utils.py
│   │   │       ├── test_aws_utils.py
│   │   │       ├── test_containerize.py
│   │   │       ├── test_delete.py
│   │   │       ├── test_docker_utils.py
│   │   │       ├── test_docker_with_role.py
│   │   │       ├── test_image_pull_failure_extended.py
│   │   │       ├── test_image_pull_failure.py
│   │   │       ├── test_infrastructure_role.py
│   │   │       ├── test_infrastructure.py
│   │   │       ├── test_integration.py
│   │   │       ├── test_main.py
│   │   │       ├── test_resource_management_api_operation.py
│   │   │       ├── test_resource_management_tool.py
│   │   │       ├── test_resource_management.py
│   │   │       ├── test_security_integration.py
│   │   │       ├── test_status_pytest.py
│   │   │       ├── test_status.py
│   │   │       ├── troubleshooting_tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── conftest.py
│   │   │       │   ├── test_detect_image_pull_failures.py
│   │   │       │   ├── test_fetch_cloudformation_status.py
│   │   │       │   ├── test_fetch_service_events.py
│   │   │       │   ├── test_fetch_task_failures.py
│   │   │       │   ├── test_fetch_task_logs.py
│   │   │       │   ├── test_get_ecs_troubleshooting_guidance.py
│   │   │       │   ├── test_is_ecr_image_security.py
│   │   │       │   └── test_utils.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── async_test_utils.py
│   │   │           ├── test_arn_parser.py
│   │   │           ├── test_config.py
│   │   │           ├── test_docker.py
│   │   │           ├── test_response_sanitization.py
│   │   │           ├── test_security_extended.py
│   │   │           ├── test_security.py
│   │   │           ├── test_templates.py
│   │   │           └── test_time_utils.py
│   │   └── uv.lock
│   ├── eks-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── eks_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_helper.py
│   │   │       ├── cloudwatch_handler.py
│   │   │       ├── cloudwatch_metrics_guidance_handler.py
│   │   │       ├── consts.py
│   │   │       ├── data
│   │   │       │   └── eks_cloudwatch_metrics_guidance.json
│   │   │       ├── eks_kb_handler.py
│   │   │       ├── eks_stack_handler.py
│   │   │       ├── iam_handler.py
│   │   │       ├── insights_handler.py
│   │   │       ├── k8s_apis.py
│   │   │       ├── k8s_client_cache.py
│   │   │       ├── k8s_handler.py
│   │   │       ├── logging_helper.py
│   │   │       ├── models.py
│   │   │       ├── scripts
│   │   │       │   └── update_eks_cloudwatch_metrics_guidance.py
│   │   │       ├── server.py
│   │   │       ├── templates
│   │   │       │   ├── eks-templates
│   │   │       │   │   └── eks-with-vpc.yaml
│   │   │       │   └── k8s-templates
│   │   │       │       ├── deployment.yaml
│   │   │       │       └── service.yaml
│   │   │       └── vpc_config_handler.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_aws_helper.py
│   │   │   ├── test_cloudwatch_handler.py
│   │   │   ├── test_cloudwatch_metrics_guidance_handler.py
│   │   │   ├── test_eks_kb_handler.py
│   │   │   ├── test_eks_stack_handler.py
│   │   │   ├── test_iam_handler.py
│   │   │   ├── test_init.py
│   │   │   ├── test_insights_handler.py
│   │   │   ├── test_k8s_apis.py
│   │   │   ├── test_k8s_client_cache.py
│   │   │   ├── test_k8s_handler.py
│   │   │   ├── test_logging_helper.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_vpc_config_handler.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── elasticache-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── elasticache_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common
│   │   │       │   ├── __init__.py
│   │   │       │   ├── connection.py
│   │   │       │   ├── decorators.py
│   │   │       │   └── server.py
│   │   │       ├── context.py
│   │   │       ├── main.py
│   │   │       └── tools
│   │   │           ├── __init__.py
│   │   │           ├── cc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── connect.py
│   │   │           │   ├── create.py
│   │   │           │   ├── delete.py
│   │   │           │   ├── describe.py
│   │   │           │   ├── modify.py
│   │   │           │   ├── parsers.py
│   │   │           │   └── processors.py
│   │   │           ├── ce
│   │   │           │   ├── __init__.py
│   │   │           │   └── get_cost_and_usage.py
│   │   │           ├── cw
│   │   │           │   ├── __init__.py
│   │   │           │   └── get_metric_statistics.py
│   │   │           ├── cwlogs
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_log_group.py
│   │   │           │   ├── describe_log_groups.py
│   │   │           │   ├── describe_log_streams.py
│   │   │           │   ├── filter_log_events.py
│   │   │           │   └── get_log_events.py
│   │   │           ├── firehose
│   │   │           │   ├── __init__.py
│   │   │           │   └── list_delivery_streams.py
│   │   │           ├── misc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── batch_apply_update_action.py
│   │   │           │   ├── batch_stop_update_action.py
│   │   │           │   ├── describe_cache_engine_versions.py
│   │   │           │   ├── describe_engine_default_parameters.py
│   │   │           │   ├── describe_events.py
│   │   │           │   └── describe_service_updates.py
│   │   │           ├── rg
│   │   │           │   ├── __init__.py
│   │   │           │   ├── complete_migration.py
│   │   │           │   ├── connect.py
│   │   │           │   ├── create.py
│   │   │           │   ├── delete.py
│   │   │           │   ├── describe.py
│   │   │           │   ├── modify.py
│   │   │           │   ├── parsers.py
│   │   │           │   ├── processors.py
│   │   │           │   ├── start_migration.py
│   │   │           │   └── test_migration.py
│   │   │           └── serverless
│   │   │               ├── __init__.py
│   │   │               ├── connect.py
│   │   │               ├── create.py
│   │   │               ├── delete.py
│   │   │               ├── describe.py
│   │   │               ├── models.py
│   │   │               └── modify.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_connection.py
│   │   │   ├── test_decorators.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── tools
│   │   │       ├── cc
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_connect_additional.py
│   │   │       │   ├── test_connect_coverage_additional.py
│   │   │       │   ├── test_connect_coverage.py
│   │   │       │   ├── test_connect.py
│   │   │       │   ├── test_create_additional.py
│   │   │       │   ├── test_create.py
│   │   │       │   ├── test_delete.py
│   │   │       │   ├── test_describe.py
│   │   │       │   ├── test_modify.py
│   │   │       │   ├── test_parsers.py
│   │   │       │   └── test_processors.py
│   │   │       ├── ce
│   │   │       │   ├── __init__.py
│   │   │       │   └── test_get_cost_and_usage.py
│   │   │       ├── cw
│   │   │       │   └── test_get_metric_statistics.py
│   │   │       ├── cwlogs
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_create_log_group.py
│   │   │       │   ├── test_describe_log_groups.py
│   │   │       │   ├── test_describe_log_streams.py
│   │   │       │   ├── test_filter_log_events.py
│   │   │       │   └── test_get_log_events.py
│   │   │       ├── firehose
│   │   │       │   └── test_list_delivery_streams.py
│   │   │       ├── misc
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_batch_apply_update_action.py
│   │   │       │   ├── test_batch_stop_update_action.py
│   │   │       │   ├── test_describe_cache_engine_versions.py
│   │   │       │   ├── test_describe_engine_default_parameters.py
│   │   │       │   ├── test_describe_events.py
│   │   │       │   └── test_describe_service_updates.py
│   │   │       ├── rg
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_complete_migration.py
│   │   │       │   ├── test_connect_additional.py
│   │   │       │   ├── test_connect_coverage_additional.py
│   │   │       │   ├── test_connect_optional_fields.py
│   │   │       │   ├── test_connect_partial_coverage.py
│   │   │       │   ├── test_connect.py
│   │   │       │   ├── test_create.py
│   │   │       │   ├── test_delete.py
│   │   │       │   ├── test_describe.py
│   │   │       │   ├── test_modify.py
│   │   │       │   ├── test_parsers.py
│   │   │       │   ├── test_processors.py
│   │   │       │   ├── test_start_migration.py
│   │   │       │   └── test_test_migration.py
│   │   │       └── serverless
│   │   │           ├── test_connect_additional.py
│   │   │           ├── test_connect_coverage_additional.py
│   │   │           ├── test_connect_optional_fields.py
│   │   │           ├── test_connect.py
│   │   │           ├── test_create.py
│   │   │           ├── test_delete.py
│   │   │           ├── test_describe.py
│   │   │           └── test_modify.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── finch-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── finch_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── build.py
│   │   │           ├── common.py
│   │   │           ├── ecr.py
│   │   │           ├── push.py
│   │   │           └── vm.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_cli_flags.py
│   │   │   ├── test_logging_configuration.py
│   │   │   ├── test_server.py
│   │   │   ├── test_utils_build.py
│   │   │   ├── test_utils_common.py
│   │   │   ├── test_utils_ecr.py
│   │   │   ├── test_utils_push.py
│   │   │   └── test_utils_vm.py
│   │   └── uv.lock
│   ├── frontend-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── frontend_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       ├── static
│   │   │       │   └── react
│   │   │       │       ├── essential-knowledge.md
│   │   │       │       └── troubleshooting.md
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           └── file_utils.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_file_utils.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   └── uv.lock
│   ├── git-repo-research-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── git_repo_research_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── defaults.py
│   │   │       ├── embeddings.py
│   │   │       ├── github_search.py
│   │   │       ├── indexer.py
│   │   │       ├── models.py
│   │   │       ├── repository.py
│   │   │       ├── search.py
│   │   │       ├── server.py
│   │   │       └── utils.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_errors_repository.py
│   │   │   ├── test_github_search_edge_cases.py
│   │   │   ├── test_graphql_github_search.py
│   │   │   ├── test_local_repository.py
│   │   │   ├── test_repository_utils.py
│   │   │   ├── test_rest_github_search.py
│   │   │   ├── test_search.py
│   │   │   ├── test_server.py
│   │   │   └── test_url_repository.py
│   │   └── uv.lock
│   ├── healthlake-mcp-server
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── healthlake_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── fhir_operations.py
│   │   │       ├── main.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── mcp_config.json
│   │   │   └── README.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_fhir_client_comprehensive.py
│   │   │   ├── test_fhir_error_scenarios.py
│   │   │   ├── test_fhir_operations.py
│   │   │   ├── test_integration_mock_based.py
│   │   │   ├── test_main_edge_cases.py
│   │   │   ├── test_main.py
│   │   │   ├── test_mcp_integration_coverage.py
│   │   │   ├── test_models_edge_cases.py
│   │   │   ├── test_models.py
│   │   │   ├── test_readonly_mode.py
│   │   │   ├── test_server_core.py
│   │   │   ├── test_server_error_handling.py
│   │   │   ├── test_server_mcp_handlers.py
│   │   │   ├── test_server_toolhandler.py
│   │   │   └── test_server_validation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── iam-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── iam_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── DESIGN_COMPLIANCE.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── get_policy_document_example.py
│   │   │   └── inline_policy_demo.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── test_context.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_inline_policies.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── lambda-tool-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── lambda_tool_mcp_server
│   │   │       ├── __init__.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── README.md
│   │   │   └── sample_functions
│   │   │       ├── customer-create
│   │   │       │   └── app.py
│   │   │       ├── customer-id-from-email
│   │   │       │   └── app.py
│   │   │       ├── customer-info-from-id
│   │   │       │   └── app.py
│   │   │       └── template.yml
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_format_lambda_response.py
│   │   │   ├── test_integration_coverage.py
│   │   │   ├── test_integration.py
│   │   │   ├── test_register_lambda_functions.py
│   │   │   ├── test_schema_integration.py
│   │   │   ├── test_server_coverage_additional.py
│   │   │   ├── test_server_coverage.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── mcp-lambda-handler
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   └── mcp_lambda_handler
│   │   │       ├── __init__.py
│   │   │       ├── mcp_lambda_handler.py
│   │   │       ├── session.py
│   │   │       └── types.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   └── test_lambda_handler.py
│   │   └── uv.lock
│   ├── memcached-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── memcached_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common
│   │   │       │   ├── config.py
│   │   │       │   ├── connection.py
│   │   │       │   └── server.py
│   │   │       ├── context.py
│   │   │       ├── main.py
│   │   │       └── tools
│   │   │           └── cache.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── ELASTICACHECONNECT.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_cache_readonly.py
│   │   │   ├── test_cache.py
│   │   │   ├── test_connection.py
│   │   │   ├── test_init.py
│   │   │   └── test_main.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── mysql-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── mysql_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── connection
│   │   │       │   ├── __init__.py
│   │   │       │   ├── abstract_db_connection.py
│   │   │       │   ├── asyncmy_pool_connection.py
│   │   │       │   ├── db_connection_singleton.py
│   │   │       │   └── rds_data_api_connection.py
│   │   │       ├── mutable_sql_detector.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_abstract_db_connection.py
│   │   │   ├── test_asyncmy_pool_connection.py
│   │   │   ├── test_db_connection_singleton.py
│   │   │   ├── test_rds_data_api_connection.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── nova-canvas-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── nova_canvas_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── models.py
│   │   │       ├── novacanvas.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_models.py
│   │   │   ├── test_novacanvas.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── openapi-mcp-server
│   │   ├── .coveragerc
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── AUTHENTICATION.md
│   │   ├── AWS_BEST_PRACTICES.md
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── openapi_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── api
│   │   │       │   ├── __init__.py
│   │   │       │   └── config.py
│   │   │       ├── auth
│   │   │       │   ├── __init__.py
│   │   │       │   ├── api_key_auth.py
│   │   │       │   ├── auth_cache.py
│   │   │       │   ├── auth_errors.py
│   │   │       │   ├── auth_factory.py
│   │   │       │   ├── auth_protocol.py
│   │   │       │   ├── auth_provider.py
│   │   │       │   ├── base_auth.py
│   │   │       │   ├── basic_auth.py
│   │   │       │   ├── bearer_auth.py
│   │   │       │   ├── cognito_auth.py
│   │   │       │   └── register.py
│   │   │       ├── patch
│   │   │       │   └── __init__.py
│   │   │       ├── prompts
│   │   │       │   ├── __init__.py
│   │   │       │   ├── generators
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── operation_prompts.py
│   │   │       │   │   └── workflow_prompts.py
│   │   │       │   ├── models.py
│   │   │       │   └── prompt_manager.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── cache_provider.py
│   │   │           ├── config.py
│   │   │           ├── error_handler.py
│   │   │           ├── http_client.py
│   │   │           ├── metrics_provider.py
│   │   │           ├── openapi_validator.py
│   │   │           └── openapi.py
│   │   ├── CHANGELOG.md
│   │   ├── DEPLOYMENT.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── OBSERVABILITY.md
│   │   ├── pyproject.toml
│   │   ├── pyrightconfig.json
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── api
│   │   │   │   └── test_config.py
│   │   │   ├── auth
│   │   │   │   ├── test_api_key_auth.py
│   │   │   │   ├── test_auth_cache.py
│   │   │   │   ├── test_auth_errors.py
│   │   │   │   ├── test_auth_factory_caching.py
│   │   │   │   ├── test_auth_factory_coverage.py
│   │   │   │   ├── test_auth_factory.py
│   │   │   │   ├── test_auth_protocol_additional.py
│   │   │   │   ├── test_auth_protocol_boost.py
│   │   │   │   ├── test_auth_protocol_coverage.py
│   │   │   │   ├── test_auth_protocol_extended.py
│   │   │   │   ├── test_auth_protocol_improved.py
│   │   │   │   ├── test_auth_protocol.py
│   │   │   │   ├── test_auth_provider_additional.py
│   │   │   │   ├── test_base_auth_coverage.py
│   │   │   │   ├── test_base_auth.py
│   │   │   │   ├── test_basic_auth.py
│   │   │   │   ├── test_bearer_auth.py
│   │   │   │   ├── test_cognito_auth_additional_coverage.py
│   │   │   │   ├── test_cognito_auth_boost_coverage.py
│   │   │   │   ├── test_cognito_auth_client_credentials.py
│   │   │   │   ├── test_cognito_auth_coverage_boost.py
│   │   │   │   ├── test_cognito_auth_exceptions.py
│   │   │   │   ├── test_cognito_auth.py
│   │   │   │   ├── test_register_coverage.py
│   │   │   │   └── test_register.py
│   │   │   ├── prompts
│   │   │   │   ├── standalone
│   │   │   │   │   ├── test_operation_prompt.py
│   │   │   │   │   ├── test_prompt_arguments.py
│   │   │   │   │   └── test_secure_operation_prompt.py
│   │   │   │   ├── test_mcp_prompt_manager_integration.py
│   │   │   │   ├── test_mcp_prompt_manager.py
│   │   │   │   ├── test_models_dict_method.py
│   │   │   │   ├── test_operation_prompts_extended.py
│   │   │   │   ├── test_prompt_manager_additional.py
│   │   │   │   ├── test_prompt_manager_comprehensive.py
│   │   │   │   ├── test_prompt_manager_coverage.py
│   │   │   │   └── test_prompt_registration.py
│   │   │   ├── README.md
│   │   │   ├── test_api_name.py
│   │   │   ├── test_cache_coverage_89.py
│   │   │   ├── test_client.py
│   │   │   ├── test_coverage_boost.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main_extended.py
│   │   │   ├── test_main.py
│   │   │   ├── test_openapi_coverage_89.py
│   │   │   ├── test_server_auth_errors.py
│   │   │   ├── test_server_coverage_boost_2.py
│   │   │   ├── test_server_coverage_boost.py
│   │   │   ├── test_server_exception_handling.py
│   │   │   ├── test_server_extended.py
│   │   │   ├── test_server_httpx_version.py
│   │   │   ├── test_server_part1.py
│   │   │   ├── test_server_route_logging.py
│   │   │   ├── test_server_signal_handlers.py
│   │   │   ├── test_server.py
│   │   │   └── utils
│   │   │       ├── test_cache_provider.py
│   │   │       ├── test_error_handler_boost.py
│   │   │       ├── test_error_handler_extended.py
│   │   │       ├── test_error_handler_fix.py
│   │   │       ├── test_error_handler.py
│   │   │       ├── test_http_client_comprehensive.py
│   │   │       ├── test_http_client_extended.py
│   │   │       ├── test_http_client_extended2.py
│   │   │       ├── test_http_client_import_error.py
│   │   │       ├── test_http_client.py
│   │   │       ├── test_metrics_provider_decorators.py
│   │   │       ├── test_metrics_provider_extended2.py
│   │   │       ├── test_metrics_provider_prometheus.py
│   │   │       ├── test_metrics_provider.py
│   │   │       ├── test_openapi_validator.py
│   │   │       └── test_openapi.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── postgres-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── postgres_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── connection
│   │   │       │   ├── __init__.py
│   │   │       │   ├── abstract_db_connection.py
│   │   │       │   ├── db_connection_singleton.py
│   │   │       │   ├── psycopg_pool_connection.py
│   │   │       │   └── rds_api_connection.py
│   │   │       ├── mutable_sql_detector.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_psycopg_connector.py
│   │   │   ├── test_server.py
│   │   │   └── test_singleton.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── prometheus-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── prometheus_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_aws_credentials.py
│   │   │   ├── test_config_manager.py
│   │   │   ├── test_consts.py
│   │   │   ├── test_coverage_gaps.py
│   │   │   ├── test_coverage_improvement.py
│   │   │   ├── test_final_coverage.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_prometheus_client.py
│   │   │   ├── test_prometheus_connection.py
│   │   │   ├── test_security_validator.py
│   │   │   ├── test_server_coverage.py
│   │   │   ├── test_tools.py
│   │   │   └── test_workspace_config.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── redshift-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── redshift_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── models.py
│   │   │       ├── redshift.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_redshift.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── s3-tables-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── s3_tables_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── constants.py
│   │   │       ├── database.py
│   │   │       ├── engines
│   │   │       │   ├── __init__.py
│   │   │       │   └── pyiceberg.py
│   │   │       ├── file_processor
│   │   │       │   ├── __init__.py
│   │   │       │   ├── csv.py
│   │   │       │   ├── parquet.py
│   │   │       │   └── utils.py
│   │   │       ├── models.py
│   │   │       ├── namespaces.py
│   │   │       ├── resources.py
│   │   │       ├── s3_operations.py
│   │   │       ├── server.py
│   │   │       ├── table_buckets.py
│   │   │       ├── tables.py
│   │   │       └── utils.py
│   │   ├── CHANGELOG.md
│   │   ├── CONTEXT.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_csv.py
│   │   │   ├── test_database.py
│   │   │   ├── test_file_processor_utils.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_namespaces.py
│   │   │   ├── test_parquet.py
│   │   │   ├── test_pyiceberg.py
│   │   │   ├── test_resources.py
│   │   │   ├── test_s3_operations.py
│   │   │   ├── test_server.py
│   │   │   ├── test_table_buckets.py
│   │   │   ├── test_tables.py
│   │   │   └── test_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── stepfunctions-tool-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── stepfunctions_tool_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_helper.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── test_aws_helper.py
│   │   │   ├── test_create_state_machine_tool.py
│   │   │   ├── test_filter_state_machines_by_tag.py
│   │   │   ├── test_format_state_machine_response.py
│   │   │   ├── test_get_schema_arn_from_state_machine_arn.py
│   │   │   ├── test_get_schema_from_registry.py
│   │   │   ├── test_invoke_express_state_machine_impl.py
│   │   │   ├── test_invoke_standard_state_machine_impl.py
│   │   │   ├── test_main.py
│   │   │   ├── test_register_state_machines.py
│   │   │   ├── test_sanitize_tool_name.py
│   │   │   ├── test_server.py
│   │   │   └── test_validate_state_machine_name.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── syntheticdata-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── syntheticdata_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── pandas_interpreter.py
│   │   │       ├── server.py
│   │   │       └── storage
│   │   │           ├── __init__.py
│   │   │           ├── base.py
│   │   │           ├── loader.py
│   │   │           └── s3.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_constants.py
│   │   │   ├── test_pandas_interpreter.py
│   │   │   ├── test_server.py
│   │   │   └── test_storage
│   │   │       ├── __init__.py
│   │   │       ├── test_loader.py
│   │   │       └── test_s3.py
│   │   └── uv.lock
│   ├── terraform-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── terraform_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── impl
│   │   │       │   ├── resources
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── terraform_aws_provider_resources_listing.py
│   │   │       │   │   └── terraform_awscc_provider_resources_listing.py
│   │   │       │   └── tools
│   │   │       │       ├── __init__.py
│   │   │       │       ├── execute_terraform_command.py
│   │   │       │       ├── execute_terragrunt_command.py
│   │   │       │       ├── run_checkov_scan.py
│   │   │       │       ├── search_aws_provider_docs.py
│   │   │       │       ├── search_awscc_provider_docs.py
│   │   │       │       ├── search_specific_aws_ia_modules.py
│   │   │       │       ├── search_user_provided_module.py
│   │   │       │       └── utils.py
│   │   │       ├── models
│   │   │       │   ├── __init__.py
│   │   │       │   └── models.py
│   │   │       ├── scripts
│   │   │       │   ├── generate_aws_provider_resources.py
│   │   │       │   ├── generate_awscc_provider_resources.py
│   │   │       │   └── scrape_aws_terraform_best_practices.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           ├── __init__.py
│   │   │           ├── AWS_PROVIDER_RESOURCES.md
│   │   │           ├── AWS_TERRAFORM_BEST_PRACTICES.md
│   │   │           ├── AWSCC_PROVIDER_RESOURCES.md
│   │   │           ├── MCP_INSTRUCTIONS.md
│   │   │           └── TERRAFORM_WORKFLOW_GUIDE.md
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_command_impl.py
│   │   │   ├── test_execute_terraform_command.py
│   │   │   ├── test_execute_terragrunt_command.py
│   │   │   ├── test_models.py
│   │   │   ├── test_parameter_annotations.py
│   │   │   ├── test_resources.py
│   │   │   ├── test_run_checkov_scan.py
│   │   │   ├── test_search_user_provided_module.py
│   │   │   ├── test_server.py
│   │   │   ├── test_tool_implementations.py
│   │   │   ├── test_utils_additional.py
│   │   │   └── test_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── timestream-for-influxdb-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── timestream_for_influxdb_mcp_server
│   │   │       ├── __init__.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── valkey-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── valkey_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common
│   │   │       │   ├── __init__.py
│   │   │       │   ├── config.py
│   │   │       │   ├── connection.py
│   │   │       │   └── server.py
│   │   │       ├── context.py
│   │   │       ├── main.py
│   │   │       ├── tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── bitmap.py
│   │   │       │   ├── hash.py
│   │   │       │   ├── hyperloglog.py
│   │   │       │   ├── json.py
│   │   │       │   ├── list.py
│   │   │       │   ├── misc.py
│   │   │       │   ├── server_management.py
│   │   │       │   ├── set.py
│   │   │       │   ├── sorted_set.py
│   │   │       │   ├── stream.py
│   │   │       │   └── string.py
│   │   │       └── version.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── ELASTICACHECONNECT.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_bitmap.py
│   │   │   ├── test_config.py
│   │   │   ├── test_connection.py
│   │   │   ├── test_hash.py
│   │   │   ├── test_hyperloglog.py
│   │   │   ├── test_init.py
│   │   │   ├── test_json_additional.py
│   │   │   ├── test_json_readonly.py
│   │   │   ├── test_json.py
│   │   │   ├── test_list_additional.py
│   │   │   ├── test_list_readonly.py
│   │   │   ├── test_list.py
│   │   │   ├── test_main.py
│   │   │   ├── test_misc.py
│   │   │   ├── test_server_management.py
│   │   │   ├── test_set_readonly.py
│   │   │   ├── test_set.py
│   │   │   ├── test_sorted_set_additional.py
│   │   │   ├── test_sorted_set_readonly.py
│   │   │   ├── test_sorted_set.py
│   │   │   ├── test_stream_additional.py
│   │   │   ├── test_stream_readonly.py
│   │   │   ├── test_stream.py
│   │   │   └── test_string.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   └── well-architected-security-mcp-server
│       ├── .python-version
│       ├── awslabs
│       │   └── well_architected_security_mcp_server
│       │       ├── __init__.py
│       │       ├── consts.py
│       │       ├── server.py
│       │       └── util
│       │           ├── __init__.py
│       │           ├── network_security.py
│       │           ├── prompt_utils.py
│       │           ├── resource_utils.py
│       │           ├── security_services.py
│       │           └── storage_security.py
│       ├── PROMPT_TEMPLATE.md
│       ├── pyproject.toml
│       ├── README.md
│       ├── tests
│       │   ├── __init__.py
│       │   ├── conftest.py
│       │   ├── README.md
│       │   ├── test_access_analyzer_fix.py
│       │   ├── test_network_security_additional.py
│       │   ├── test_network_security.py
│       │   ├── test_prompt_utils_coverage.py
│       │   ├── test_prompt_utils.py
│       │   ├── test_resource_utils_fix.py
│       │   ├── test_resource_utils.py
│       │   ├── test_security_services_additional.py
│       │   ├── test_security_services_coverage.py
│       │   ├── test_security_services.py
│       │   ├── test_server_additional.py
│       │   ├── test_server_coverage.py
│       │   ├── test_server_prompts.py
│       │   ├── test_server_security_findings.py
│       │   ├── test_server.py
│       │   ├── test_storage_security_additional.py
│       │   ├── test_storage_security_comprehensive.py
│       │   ├── test_storage_security_edge_cases.py
│       │   ├── test_storage_security_recommendations.py
│       │   ├── test_storage_security.py
│       │   └── test_user_agent_config.py
│       └── uv.lock
└── VIBE_CODING_TIPS_TRICKS.md
```

# Files

--------------------------------------------------------------------------------
/src/aws-dataprocessing-mcp-server/awslabs/aws_dataprocessing_mcp_server/handlers/commons/common_resource_handler.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 | """Common Resource handler for the Data Processing MCP Server."""
  16 | 
  17 | import json
  18 | import os
  19 | from awslabs.aws_dataprocessing_mcp_server.models.common_resource_models import (
  20 |     AddInlinePolicyResponse,
  21 |     AnalyzeS3UsageResponse,
  22 |     CreateRoleResponse,
  23 |     ListS3BucketsResponse,
  24 |     PolicySummary,
  25 |     RoleDescriptionResponse,
  26 |     RoleSummary,
  27 |     ServiceRolesResponse,
  28 |     UploadToS3Response,
  29 | )
  30 | from awslabs.aws_dataprocessing_mcp_server.utils.aws_helper import AwsHelper
  31 | from awslabs.aws_dataprocessing_mcp_server.utils.logging_helper import (
  32 |     LogLevel,
  33 |     log_with_request_id,
  34 | )
  35 | from botocore.exceptions import ClientError
  36 | from datetime import datetime
  37 | from mcp.server.fastmcp import Context
  38 | from mcp.types import TextContent
  39 | from pydantic import Field
  40 | from typing import Annotated, Any, Dict, List, Optional, Union
  41 | 
  42 | 
  43 | class CommonResourceHandler:
  44 |     """Handler for AWS Common Resource operations in the Data Processing MCP Server.
  45 | 
  46 |     This class provides tools for managing IAM roles and policies, S3 buckets and objects,
  47 |     including describing roles with their attached policies, adding inline permissions
  48 |     to policies, creating roles with specific trust relationships for data processing
  49 |     services like Glue, EMR, and Athena, and managing S3 resources.
  50 |     """
  51 | 
  52 |     def __init__(self, mcp, allow_write: bool = False):
  53 |         """Initialize the Common Resource handler.
  54 | 
  55 |         Args:
  56 |             mcp: The MCP server instance
  57 |             allow_write: Whether to enable write access (default: False)
  58 |         """
  59 |         self.mcp = mcp
  60 |         self.iam_client = AwsHelper.create_boto3_client('iam')
  61 |         self.s3_client = AwsHelper.create_boto3_client('s3')
  62 |         self.allow_write = allow_write
  63 | 
  64 |         # Register IAM tools
  65 |         self.mcp.tool(name='add_inline_policy')(self.add_inline_policy)
  66 |         self.mcp.tool(name='get_policies_for_role')(self.get_policies_for_role)
  67 |         self.mcp.tool(name='create_data_processing_role')(self.create_data_processing_role)
  68 |         self.mcp.tool(name='get_roles_for_service')(self.get_roles_for_service)
  69 | 
  70 |         # Register S3 tools
  71 |         self.mcp.tool(name='list_s3_buckets')(self.list_s3_buckets)
  72 |         self.mcp.tool(name='upload_to_s3')(self.upload_to_s3)
  73 |         self.mcp.tool(name='analyze_s3_usage_for_data_processing')(
  74 |             self.analyze_s3_usage_for_data_processing
  75 |         )
  76 | 
  77 |     # ============================================================================
  78 |     # IAM Operations
  79 |     # ============================================================================
  80 | 
  81 |     async def get_policies_for_role(
  82 |         self,
  83 |         ctx: Context,
  84 |         role_name: Annotated[
  85 |             str,
  86 |             Field(
  87 |                 description='Name of the IAM role to get policies for. The role must exist in your AWS account.',
  88 |             ),
  89 |         ],
  90 |     ) -> RoleDescriptionResponse:
  91 |         """Get all policies attached to an IAM role.
  92 | 
  93 |         This tool retrieves all policies associated with an IAM role, providing a comprehensive view
  94 |         of the role's permissions and trust relationships. It helps you understand the current
  95 |         permissions, identify missing or excessive permissions, troubleshoot data processing issues,
  96 |         and verify trust relationships for service roles.
  97 | 
  98 |         ## Requirements
  99 |         - The role must exist in your AWS account
 100 |         - Valid AWS credentials with permissions to read IAM role information
 101 | 
 102 |         ## Response Information
 103 |         The response includes role ARN, assume role policy document (trust relationships),
 104 |         role description, managed policies with their documents, and inline policies with
 105 |         their documents.
 106 | 
 107 |         ## Usage Tips
 108 |         - Use this tool before adding new permissions to understand existing access
 109 |         - Check the assume role policy to verify which services or roles can assume this role
 110 |         - Look for overly permissive policies that might pose security risks
 111 |         - Use with add_inline_policy to implement least-privilege permissions
 112 |         - For Glue jobs, ensure the role has access to required data sources and targets
 113 |         - For EMR clusters, verify EC2 instance profile permissions
 114 |         - For Athena queries, check S3 bucket access permissions
 115 | 
 116 |         Args:
 117 |             ctx: The MCP context
 118 |             role_name: Name of the IAM role to get policies for
 119 | 
 120 |         Returns:
 121 |             RoleDescriptionResponse: Detailed information about the role's policies
 122 |         """
 123 |         try:
 124 |             log_with_request_id(
 125 |                 ctx,
 126 |                 LogLevel.INFO,
 127 |                 f'Common Resource Handler - Tool: get_policies_for_role - Operation: describe role policies for {role_name}',
 128 |             )
 129 | 
 130 |             # Get role details
 131 |             role_response = self.iam_client.get_role(RoleName=role_name)
 132 |             role = role_response['Role']
 133 | 
 134 |             # Get attached managed policies
 135 |             managed_policies = self._get_managed_policies(ctx, role_name)
 136 | 
 137 |             # Get inline policies
 138 |             inline_policies = self._get_inline_policies(ctx, role_name)
 139 | 
 140 |             # Parse the assume role policy document if it's a string, otherwise use it directly
 141 |             if isinstance(role['AssumeRolePolicyDocument'], str):
 142 |                 assume_role_policy_document = json.loads(role['AssumeRolePolicyDocument'])
 143 |             else:
 144 |                 assume_role_policy_document = role['AssumeRolePolicyDocument']
 145 | 
 146 |             # Create the response
 147 |             return RoleDescriptionResponse(
 148 |                 isError=False,
 149 |                 content=[
 150 |                     TextContent(
 151 |                         type='text',
 152 |                         text=f'Successfully retrieved details for IAM role: {role_name}',
 153 |                     )
 154 |                 ],
 155 |                 role_arn=role['Arn'],
 156 |                 assume_role_policy_document=assume_role_policy_document,
 157 |                 description=role.get('Description'),
 158 |                 managed_policies=managed_policies,
 159 |                 inline_policies=inline_policies,
 160 |             )
 161 |         except Exception as e:
 162 |             error_message = f'Failed to describe IAM role: {str(e)}'
 163 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 164 | 
 165 |             # Return a response with error status
 166 |             return RoleDescriptionResponse(
 167 |                 isError=True,
 168 |                 content=[TextContent(type='text', text=error_message)],
 169 |                 role_arn='',
 170 |                 assume_role_policy_document={},
 171 |                 description=None,
 172 |                 managed_policies=[],
 173 |                 inline_policies=[],
 174 |             )
 175 | 
 176 |     async def add_inline_policy(
 177 |         self,
 178 |         ctx: Context,
 179 |         policy_name: Annotated[
 180 |             str,
 181 |             Field(
 182 |                 description='Name of the inline policy to create. Must be unique within the role.',
 183 |             ),
 184 |         ],
 185 |         role_name: Annotated[
 186 |             str,
 187 |             Field(
 188 |                 description='Name of the IAM role to add the policy to. The role must exist.',
 189 |             ),
 190 |         ],
 191 |         permissions: Annotated[
 192 |             Union[Dict[str, Any], List[Dict[str, Any]]],
 193 |             Field(
 194 |                 description="""Permissions to include in the policy as IAM policy statements in JSON format.
 195 |             Can be either a single statement object or an array of statement objects.""",
 196 |             ),
 197 |         ],
 198 |     ) -> AddInlinePolicyResponse:
 199 |         """Add a new inline policy to an IAM role.
 200 | 
 201 |         This tool creates a new inline policy with the specified permissions and adds it to an IAM role.
 202 |         Inline policies are embedded within the role and cannot be attached to multiple roles. Commonly used
 203 |         for granting data processing services access to AWS resources, enabling Glue jobs to access data sources,
 204 |         and configuring permissions for CloudWatch logging and S3 access.
 205 | 
 206 |         ## Requirements
 207 |         - The server must be run with the `--allow-write` flag
 208 |         - The role must exist in your AWS account
 209 |         - The policy name must be unique within the role
 210 |         - You cannot modify existing policies with this tool
 211 | 
 212 |         ## Permission Format
 213 |         The permissions parameter can be either a single policy statement or a list of statements.
 214 | 
 215 |         ### Single Statement Example
 216 |         ```json
 217 |         {
 218 |             "Effect": "Allow",
 219 |             "Action": ["s3:GetObject", "s3:PutObject"],
 220 |             "Resource": "arn:aws:s3:::example-bucket/*"
 221 |         }
 222 |         ```
 223 | 
 224 |         ## Common Data Processing Permission Examples
 225 | 
 226 |         ### Glue Job Permissions
 227 |         ```json
 228 |         {
 229 |             "Effect": "Allow",
 230 |             "Action": [
 231 |                 "glue:*",
 232 |                 "s3:GetObject",
 233 |                 "s3:PutObject",
 234 |                 "s3:DeleteObject",
 235 |                 "s3:ListBucket",
 236 |                 "iam:PassRole"
 237 |             ],
 238 |             "Resource": "*"
 239 |         }
 240 |         ```
 241 | 
 242 |         ### EMR Cluster Permissions
 243 |         ```json
 244 |         {
 245 |             "Effect": "Allow",
 246 |             "Action": [
 247 |                 "elasticmapreduce:*",
 248 |                 "ec2:DescribeInstances",
 249 |                 "ec2:DescribeSecurityGroups",
 250 |                 "s3:ListBucket",
 251 |                 "s3:GetObject",
 252 |                 "s3:PutObject"
 253 |             ],
 254 |             "Resource": "*"
 255 |         }
 256 |         ```
 257 | 
 258 |         ### Athena Query Permissions
 259 |         ```json
 260 |         {
 261 |             "Effect": "Allow",
 262 |             "Action": [
 263 |                 "athena:*",
 264 |                 "glue:GetDatabase",
 265 |                 "glue:GetTable",
 266 |                 "glue:GetPartition",
 267 |                 "s3:GetObject",
 268 |                 "s3:ListBucket",
 269 |                 "s3:PutObject"
 270 |             ],
 271 |             "Resource": "*"
 272 |         }
 273 |         ```
 274 | 
 275 |         ## Usage Tips
 276 |         - Follow the principle of least privilege by granting only necessary permissions
 277 |         - Use specific resources rather than "*" whenever possible
 278 |         - Consider using conditions to further restrict permissions
 279 |         - Group related permissions into logical policies with descriptive names
 280 | 
 281 |         Args:
 282 |             ctx: The MCP context
 283 |             policy_name: Name of the new inline policy to create
 284 |             role_name: Name of the role to add the policy to
 285 |             permissions: Permissions to include in the policy (in JSON format)
 286 | 
 287 |         Returns:
 288 |             AddInlinePolicyResponse: Information about the created policy
 289 |         """
 290 |         try:
 291 |             log_with_request_id(
 292 |                 ctx,
 293 |                 LogLevel.INFO,
 294 |                 f"Common Resource Handler - Tool: add_inline_policy - Operation: add inline policy '{policy_name}' to role '{role_name}'",
 295 |             )
 296 | 
 297 |             # Check if write access is disabled
 298 |             if not self.allow_write:
 299 |                 error_message = 'Adding inline policies requires --allow-write flag'
 300 |                 log_with_request_id(ctx, LogLevel.ERROR, error_message)
 301 |                 return AddInlinePolicyResponse(
 302 |                     isError=True,
 303 |                     content=[TextContent(type='text', text=error_message)],
 304 |                     policy_name=policy_name,
 305 |                     role_name=role_name,
 306 |                     permissions_added={},
 307 |                 )
 308 | 
 309 |             # Create the inline policy
 310 |             return self._create_inline_policy(ctx, role_name, policy_name, permissions)
 311 | 
 312 |         except Exception as e:
 313 |             error_message = f'Failed to create inline policy: {str(e)}'
 314 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 315 | 
 316 |             # Return a response with error status
 317 |             return AddInlinePolicyResponse(
 318 |                 isError=True,
 319 |                 content=[TextContent(type='text', text=error_message)],
 320 |                 policy_name=policy_name,
 321 |                 role_name=role_name,
 322 |                 permissions_added={},
 323 |             )
 324 | 
 325 |     async def create_data_processing_role(
 326 |         self,
 327 |         ctx: Context,
 328 |         role_name: Annotated[
 329 |             str,
 330 |             Field(
 331 |                 description='Name of the IAM role to create. Must be unique within your AWS account.',
 332 |             ),
 333 |         ],
 334 |         service_type: Annotated[
 335 |             str,
 336 |             Field(
 337 |                 description="Type of data processing service: 'glue', 'emr', or 'athena'.",
 338 |             ),
 339 |         ],
 340 |         description: Annotated[
 341 |             Optional[str],
 342 |             Field(
 343 |                 description='Optional description for the IAM role.',
 344 |             ),
 345 |         ] = None,
 346 |         managed_policy_arns: Annotated[
 347 |             Optional[List[str]],
 348 |             Field(
 349 |                 description='Optional list of managed policy ARNs to attach to the role.',
 350 |             ),
 351 |         ] = None,
 352 |         inline_policy: Annotated[
 353 |             Optional[Dict[str, Any]],
 354 |             Field(
 355 |                 description='Optional inline policy to add to the role.',
 356 |             ),
 357 |         ] = None,
 358 |     ) -> CreateRoleResponse:
 359 |         """Create a new IAM role for data processing services.
 360 | 
 361 |         This tool creates a new IAM role with the appropriate trust relationship for the specified
 362 |         data processing service (Glue, EMR, or Athena). It can also attach managed policies and
 363 |         add an inline policy to the role.
 364 | 
 365 |         ## Requirements
 366 |         - The server must be run with the `--allow-write` flag
 367 |         - The role name must be unique within your AWS account
 368 |         - Valid AWS credentials with permissions to create IAM roles
 369 | 
 370 |         ## Service Types
 371 |         - **glue**: Creates a role that can be assumed by the Glue service
 372 |         - **emr**: Creates a role that can be assumed by the EMR service
 373 |         - **athena**: Creates a role that can be assumed by the Athena service
 374 | 
 375 |         ## Common Managed Policies. add these policies
 376 |         - Glue: 'arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole'
 377 |         - EMR: 'arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole'
 378 |         - Athena: 'arn:aws:iam::aws:policy/service-role/AmazonAthenaFullAccess'
 379 | 
 380 |         ## Usage Tips
 381 |         - Always provide a descriptive name and description for the role
 382 |         - Attach only the necessary managed policies to follow least privilege
 383 |         - Use inline policies for custom permissions specific to your use case
 384 |         - Consider adding S3 access permissions for data sources and targets
 385 | 
 386 |         Args:
 387 |             ctx: The MCP context
 388 |             role_name: Name of the IAM role to create
 389 |             service_type: Type of data processing service
 390 |             description: Optional description for the IAM role
 391 |             managed_policy_arns: Optional list of managed policy ARNs to attach
 392 |             inline_policy: Optional inline policy to add to the role
 393 | 
 394 |         Returns:
 395 |             CreateRoleResponse: Information about the created role
 396 |         """
 397 |         try:
 398 |             log_with_request_id(
 399 |                 ctx,
 400 |                 LogLevel.INFO,
 401 |                 f"Common Resource Handler - Tool: create_data_processing_role - Operation: create role '{role_name}' for service '{service_type}'",
 402 |             )
 403 | 
 404 |             # Check if write access is disabled
 405 |             if not self.allow_write:
 406 |                 error_message = 'Creating roles requires --allow-write flag'
 407 |                 log_with_request_id(ctx, LogLevel.ERROR, error_message)
 408 |                 return CreateRoleResponse(
 409 |                     isError=True,
 410 |                     content=[TextContent(type='text', text=error_message)],
 411 |                     role_name=role_name,
 412 |                     role_arn='',
 413 |                 )
 414 | 
 415 |             # Validate service type
 416 |             if service_type not in ['glue', 'emr', 'athena']:
 417 |                 error_message = (
 418 |                     f'Invalid service type: {service_type}. Must be one of: glue, emr, athena'
 419 |                 )
 420 |                 log_with_request_id(ctx, LogLevel.ERROR, error_message)
 421 |                 return CreateRoleResponse(
 422 |                     isError=True,
 423 |                     content=[TextContent(type='text', text=error_message)],
 424 |                     role_name=role_name,
 425 |                     role_arn='',
 426 |                 )
 427 | 
 428 |             # Create the trust relationship based on service type
 429 |             trust_relationship = self._get_trust_relationship_for_service(service_type)
 430 | 
 431 |             # Create the role
 432 |             log_with_request_id(
 433 |                 ctx, LogLevel.INFO, f'Creating IAM role: {role_name} for {service_type}'
 434 |             )
 435 | 
 436 |             create_role_params = {
 437 |                 'RoleName': role_name,
 438 |                 'AssumeRolePolicyDocument': json.dumps(trust_relationship),
 439 |             }
 440 | 
 441 |             if description:
 442 |                 create_role_params['Description'] = description
 443 | 
 444 |             role_response = self.iam_client.create_role(**create_role_params)
 445 |             role_arn = role_response['Role']['Arn']
 446 | 
 447 |             # Attach managed policies if provided
 448 |             if managed_policy_arns:
 449 |                 for policy_arn in managed_policy_arns:
 450 |                     log_with_request_id(
 451 |                         ctx,
 452 |                         LogLevel.INFO,
 453 |                         f'Attaching managed policy {policy_arn} to role {role_name}',
 454 |                     )
 455 |                     self.iam_client.attach_role_policy(RoleName=role_name, PolicyArn=policy_arn)
 456 | 
 457 |             # Add inline policy if provided
 458 |             if inline_policy:
 459 |                 policy_name = f'{role_name}-inline-policy'
 460 |                 log_with_request_id(
 461 |                     ctx,
 462 |                     LogLevel.INFO,
 463 |                     f'Adding inline policy {policy_name} to role {role_name}',
 464 |                 )
 465 |                 policy_document = {
 466 |                     'Version': '2012-10-17',
 467 |                     'Statement': (
 468 |                         inline_policy if isinstance(inline_policy, list) else [inline_policy]
 469 |                     ),
 470 |                 }
 471 |                 self.iam_client.put_role_policy(
 472 |                     RoleName=role_name,
 473 |                     PolicyName=policy_name,
 474 |                     PolicyDocument=json.dumps(policy_document),
 475 |                 )
 476 | 
 477 |             return CreateRoleResponse(
 478 |                 isError=False,
 479 |                 content=[
 480 |                     TextContent(
 481 |                         type='text',
 482 |                         text=f'Successfully created IAM role {role_name} for {service_type}',
 483 |                     )
 484 |                 ],
 485 |                 role_name=role_name,
 486 |                 role_arn=role_arn,
 487 |             )
 488 | 
 489 |         except Exception as e:
 490 |             error_message = f'Failed to create IAM role: {str(e)}'
 491 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 492 | 
 493 |             # Return a response with error status
 494 |             return CreateRoleResponse(
 495 |                 isError=True,
 496 |                 content=[TextContent(type='text', text=error_message)],
 497 |                 role_name=role_name,
 498 |                 role_arn='',
 499 |             )
 500 | 
 501 |     async def get_roles_for_service(
 502 |         self,
 503 |         ctx: Context,
 504 |         service_type: Annotated[
 505 |             str,
 506 |             Field(
 507 |                 description="Type of data processing service: 'glue', 'emr', 'athena', or other AWS service name.",
 508 |             ),
 509 |         ],
 510 |     ) -> ServiceRolesResponse:
 511 |         """Get all IAM roles that can be assumed by a specific AWS service.
 512 | 
 513 |         This tool retrieves all IAM roles in your AWS account that have a trust relationship
 514 |         with the specified service. It helps you identify which roles can be used for services
 515 |         like Glue jobs, EMR clusters, or Athena queries, making it easier to select the appropriate
 516 |         role when creating these resources.
 517 | 
 518 |         ## Service Types
 519 |         Common service types include:
 520 |         - **glue**: AWS Glue service (glue.amazonaws.com)
 521 |         - **emr**: Amazon EMR service (elasticmapreduce.amazonaws.com)
 522 |         - **athena**: Amazon Athena service (athena.amazonaws.com)
 523 |         - You can also specify other AWS service principals
 524 | 
 525 |         ## Response Information
 526 |         The response includes a list of roles that can be assumed by the specified service,
 527 |         with details such as role name, ARN, description, creation date, and the full
 528 |         assume role policy document.
 529 | 
 530 |         ## Usage Tips
 531 |         - Use this tool to find existing roles before creating new ones
 532 |         - Verify that roles have the necessary permissions for your use case
 533 |         - For Glue jobs, look for roles with AWSGlueServiceRole or similar policies
 534 |         - For EMR clusters, look for roles with AmazonElasticMapReduceRole or similar policies
 535 |         - For Athena queries, look for roles with AmazonAthenaFullAccess or similar policies
 536 | 
 537 |         Args:
 538 |             ctx: The MCP context
 539 |             service_type: Type of data processing service
 540 | 
 541 |         Returns:
 542 |             ServiceRolesResponse: List of roles that can be assumed by the specified service
 543 |         """
 544 |         try:
 545 |             log_with_request_id(
 546 |                 ctx,
 547 |                 LogLevel.INFO,
 548 |                 f"Common Resource Handler - Tool: get_roles_for_service - Operation: list roles for service '{service_type}'",
 549 |             )
 550 | 
 551 |             # Map service type to service principal
 552 |             service_principal = self._get_service_principal(service_type)
 553 | 
 554 |             # List all roles
 555 |             roles = []
 556 |             paginator = self.iam_client.get_paginator('list_roles')
 557 | 
 558 |             for page in paginator.paginate():
 559 |                 for role in page.get('Roles', []):
 560 |                     # Parse the assume role policy document
 561 |                     if isinstance(role.get('AssumeRolePolicyDocument'), str):
 562 |                         assume_role_policy_document = json.loads(role['AssumeRolePolicyDocument'])
 563 |                     else:
 564 |                         assume_role_policy_document = role.get('AssumeRolePolicyDocument', {})
 565 | 
 566 |                     # Check if the role can be assumed by the specified service
 567 |                     if self._can_be_assumed_by_service(
 568 |                         assume_role_policy_document, service_principal
 569 |                     ):
 570 |                         roles.append(
 571 |                             RoleSummary(
 572 |                                 role_name=role['RoleName'],
 573 |                                 role_arn=role['Arn'],
 574 |                                 description=role.get('Description'),
 575 |                                 create_date=role['CreateDate'].isoformat(),
 576 |                                 assume_role_policy_document=assume_role_policy_document,
 577 |                             )
 578 |                         )
 579 | 
 580 |             return ServiceRolesResponse(
 581 |                 isError=False,
 582 |                 content=[
 583 |                     TextContent(
 584 |                         type='text',
 585 |                         text=f'Successfully retrieved {len(roles)} roles for service: {service_type}',
 586 |                     )
 587 |                 ],
 588 |                 service_type=service_type,
 589 |                 roles=roles,
 590 |             )
 591 |         except Exception as e:
 592 |             error_message = f'Failed to list IAM roles for service {service_type}: {str(e)}'
 593 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 594 | 
 595 |             # Return a response with error status
 596 |             return ServiceRolesResponse(
 597 |                 isError=True,
 598 |                 content=[TextContent(type='text', text=error_message)],
 599 |                 service_type=service_type,
 600 |                 roles=[],
 601 |             )
 602 | 
 603 |     # ============================================================================
 604 |     # S3 Operations
 605 |     # ============================================================================
 606 | 
 607 |     async def list_s3_buckets(
 608 |         self,
 609 |         ctx: Context,
 610 |         region: Annotated[
 611 |             Optional[str],
 612 |             Field(
 613 |                 description='AWS region to filter buckets by (defaults to AWS_REGION environment variable)',
 614 |             ),
 615 |         ] = None,
 616 |     ) -> ListS3BucketsResponse:
 617 |         """List S3 buckets that have 'glue' in their name and are in the specified region.
 618 | 
 619 |         This tool helps identify S3 buckets commonly used for data processing workflows,
 620 |         particularly those related to AWS Glue operations. It provides usage statistics
 621 |         and idle time information to help with resource management.
 622 | 
 623 |         ## Requirements
 624 |         - Valid AWS credentials with permissions to list S3 buckets
 625 |         - S3:ListAllMyBuckets permission
 626 | 
 627 |         ## Response Information
 628 |         The response includes bucket name, creation date, region, object count,
 629 |         last modified date, and idle time analysis.
 630 | 
 631 |         ## Usage Tips
 632 |         - Use this tool to find existing data processing buckets before creating new ones
 633 |         - Monitor idle buckets that haven't been accessed for 90+ days
 634 |         - Verify bucket regions match your data processing service regions
 635 |         - Check object counts to understand bucket usage patterns
 636 | 
 637 |         Args:
 638 |             ctx: The MCP context
 639 |             region: AWS region to filter buckets by
 640 | 
 641 |         Returns:
 642 |             ListS3BucketsResponse: Information about matching S3 buckets
 643 |         """
 644 |         try:
 645 |             log_with_request_id(
 646 |                 ctx,
 647 |                 LogLevel.INFO,
 648 |                 "Common Resource Handler - Tool: list_s3_buckets - Operation: list S3 buckets with 'glue' in name",
 649 |             )
 650 | 
 651 |             # Use provided region or get from environment variable
 652 |             aws_region = region or os.getenv('AWS_REGION', 'us-east-1')
 653 | 
 654 |             # Get all buckets
 655 |             response = self.s3_client.list_buckets()
 656 |             buckets = response['Buckets']
 657 | 
 658 |             # Initialize result
 659 |             result = (
 660 |                 f"Looking for S3 buckets with 'glue' in their name in region {aws_region}:\n\n"
 661 |             )
 662 | 
 663 |             # Track matching buckets
 664 |             matching_buckets = []
 665 |             bucket_details = []
 666 | 
 667 |             # Process each bucket
 668 |             for bucket in buckets:
 669 |                 bucket_name = bucket['Name']
 670 |                 creation_date = bucket['CreationDate'].strftime('%Y-%m-%d')
 671 | 
 672 |                 # Check if bucket name contains 'glue'
 673 |                 if 'glue' in bucket_name.lower():
 674 |                     try:
 675 |                         # Get bucket location
 676 |                         location_response = self.s3_client.get_bucket_location(Bucket=bucket_name)
 677 |                         location = location_response.get('LocationConstraint', 'us-east-1')
 678 |                         if location is None:  # us-east-1 returns None
 679 |                             location = 'us-east-1'
 680 | 
 681 |                         # Check if bucket is in the specified region
 682 |                         if location.lower() == aws_region.lower():
 683 |                             matching_buckets.append(bucket)
 684 | 
 685 |                             # Get bucket objects (limited to 1000 for performance)
 686 |                             objects_response = self.s3_client.list_objects_v2(
 687 |                                 Bucket=bucket_name, MaxKeys=1000
 688 |                             )
 689 |                             object_count = objects_response.get('KeyCount', 0)
 690 | 
 691 |                             # Check if truncated (more than 1000 objects)
 692 |                             if objects_response.get('IsTruncated', False):
 693 |                                 object_count = f'{object_count}+ (truncated)'
 694 | 
 695 |                             # Get last modified date of most recent object if any objects exist
 696 |                             last_modified = 'N/A'
 697 |                             if (
 698 |                                 object_count
 699 |                                 and 'Contents' in objects_response
 700 |                                 and objects_response['Contents']
 701 |                             ):
 702 |                                 # Sort by last modified date in descending order
 703 |                                 sorted_objects = sorted(
 704 |                                     objects_response['Contents'],
 705 |                                     key=lambda x: x['LastModified'],
 706 |                                     reverse=True,
 707 |                                 )
 708 |                                 last_modified = sorted_objects[0]['LastModified'].strftime(
 709 |                                     '%Y-%m-%d'
 710 |                                 )
 711 | 
 712 |                             # Calculate idle time
 713 |                             if last_modified != 'N/A':
 714 |                                 last_modified_date = datetime.strptime(last_modified, '%Y-%m-%d')
 715 |                                 idle_days = (datetime.now() - last_modified_date).days
 716 |                                 idle_status = f'{idle_days} days'
 717 | 
 718 |                                 # Highlight idle buckets
 719 |                                 if idle_days > 90:
 720 |                                     idle_status += ' (IDLE > 90 days)'
 721 |                             else:
 722 |                                 idle_status = 'N/A'
 723 | 
 724 |                             # Store bucket details
 725 |                             bucket_info = {
 726 |                                 'name': bucket_name,
 727 |                                 'creation_date': creation_date,
 728 |                                 'region': location,
 729 |                                 'object_count': str(object_count),
 730 |                                 'last_modified': last_modified,
 731 |                                 'idle_status': idle_status,
 732 |                             }
 733 |                             bucket_details.append(bucket_info)
 734 | 
 735 |                             # Add bucket info to result
 736 |                             result += f'Bucket: {bucket_name}\n'
 737 |                             result += f'  Created: {creation_date}\n'
 738 |                             result += f'  Region: {location}\n'
 739 |                             result += f'  Objects: {object_count}\n'
 740 |                             result += f'  Last Modified: {last_modified}\n'
 741 |                             result += f'  Idle Time: {idle_status}\n\n'
 742 | 
 743 |                     except ClientError as e:
 744 |                         result += f'Bucket: {bucket_name}\n'
 745 |                         result += f'  Created: {creation_date}\n'
 746 |                         result += f'  Error getting details: {str(e)}\n\n'
 747 | 
 748 |             # Add summary
 749 |             if matching_buckets:
 750 |                 result += f"Found {len(matching_buckets)} buckets with 'glue' in their name in region {aws_region}."
 751 |             else:
 752 |                 result += f"No buckets found with 'glue' in their name in region {aws_region}."
 753 | 
 754 |             return ListS3BucketsResponse(
 755 |                 isError=False,
 756 |                 content=[TextContent(type='text', text=result)],
 757 |                 region=aws_region,
 758 |                 bucket_count=len(matching_buckets),
 759 |                 buckets=bucket_details,
 760 |             )
 761 | 
 762 |         except ClientError as e:
 763 |             error_message = f'AWS Error: {str(e)}'
 764 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 765 |             return ListS3BucketsResponse(
 766 |                 isError=True,
 767 |                 content=[TextContent(type='text', text=error_message)],
 768 |                 region=region or 'unknown',
 769 |                 bucket_count=0,
 770 |                 buckets=[],
 771 |             )
 772 |         except Exception as e:
 773 |             error_message = f'Error: {str(e)}'
 774 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 775 |             return ListS3BucketsResponse(
 776 |                 isError=True,
 777 |                 content=[TextContent(type='text', text=error_message)],
 778 |                 region=region or 'unknown',
 779 |                 bucket_count=0,
 780 |                 buckets=[],
 781 |             )
 782 | 
 783 |     async def upload_to_s3(
 784 |         self,
 785 |         ctx: Context,
 786 |         code_content: Annotated[
 787 |             str,
 788 |             Field(
 789 |                 description='String containing Python code to upload',
 790 |             ),
 791 |         ],
 792 |         bucket_name: Annotated[
 793 |             str,
 794 |             Field(
 795 |                 description='Name of the S3 bucket',
 796 |             ),
 797 |         ],
 798 |         s3_key: Annotated[
 799 |             str,
 800 |             Field(
 801 |                 description='S3 object key (path within the bucket)',
 802 |             ),
 803 |         ],
 804 |         make_public: Annotated[
 805 |             bool,
 806 |             Field(
 807 |                 description='Whether to make the file publicly accessible (default: False)',
 808 |             ),
 809 |         ] = False,
 810 |     ) -> UploadToS3Response:
 811 |         """Upload Python code content directly to an S3 bucket using putObject.
 812 | 
 813 |         This tool uploads Python code content directly to an S3 bucket, commonly used
 814 |         for storing Glue job scripts, EMR step scripts, or other data processing code.
 815 |         The uploaded file can be referenced by data processing services.
 816 | 
 817 |         ## Requirements
 818 |         - The server must be run with the `--allow-write` flag
 819 |         - Valid AWS credentials with permissions to write to the specified S3 bucket
 820 |         - The bucket must exist and be accessible
 821 | 
 822 |         ## Usage Tips
 823 |         - Use descriptive S3 keys that include version information or timestamps
 824 |         - Store scripts in organized folder structures (e.g., glue-jobs/, emr-steps/)
 825 |         - Consider using versioning on the S3 bucket for script history
 826 |         - The returned S3 URI can be used directly in Glue job configurations
 827 | 
 828 |         Args:
 829 |             ctx: The MCP context
 830 |             code_content: String containing Python code to upload
 831 |             bucket_name: Name of the S3 bucket
 832 |             s3_key: S3 object key (path within the bucket)
 833 |             make_public: Whether to make the file publicly accessible
 834 | 
 835 |         Returns:
 836 |             UploadToS3Response: Information about the uploaded file
 837 |         """
 838 |         try:
 839 |             log_with_request_id(
 840 |                 ctx,
 841 |                 LogLevel.INFO,
 842 |                 f'Common Resource Handler - Tool: upload_to_s3 - Operation: upload code to {bucket_name}/{s3_key}',
 843 |             )
 844 | 
 845 |             # Check if write access is disabled
 846 |             if not self.allow_write:
 847 |                 error_message = 'Uploading to S3 requires --allow-write flag'
 848 |                 log_with_request_id(ctx, LogLevel.ERROR, error_message)
 849 |                 return UploadToS3Response(
 850 |                     isError=True,
 851 |                     content=[TextContent(type='text', text=error_message)],
 852 |                     s3_uri='',
 853 |                     bucket_name=bucket_name,
 854 |                     s3_key=s3_key,
 855 |                 )
 856 | 
 857 |             # Check if bucket exists
 858 |             try:
 859 |                 self.s3_client.head_bucket(Bucket=bucket_name)
 860 |             except ClientError as e:
 861 |                 if e.response['Error']['Code'] == '404':
 862 |                     error_message = f"Bucket '{bucket_name}' does not exist"
 863 |                 elif e.response['Error']['Code'] == '403':
 864 |                     error_message = f"Access denied to bucket '{bucket_name}'"
 865 |                 else:
 866 |                     error_message = f'Error checking bucket: {str(e)}'
 867 | 
 868 |                 log_with_request_id(ctx, LogLevel.ERROR, error_message)
 869 |                 return UploadToS3Response(
 870 |                     isError=True,
 871 |                     content=[TextContent(type='text', text=error_message)],
 872 |                     s3_uri='',
 873 |                     bucket_name=bucket_name,
 874 |                     s3_key=s3_key,
 875 |                 )
 876 | 
 877 |             # Upload code content using putObject
 878 |             self.s3_client.put_object(
 879 |                 Body=code_content,
 880 |                 Bucket=bucket_name,
 881 |                 Key=s3_key,
 882 |                 ContentType='text/x-python',
 883 |             )
 884 | 
 885 |             # Make public if requested
 886 |             if make_public:
 887 |                 self.s3_client.put_object_acl(Bucket=bucket_name, Key=s3_key, ACL='public-read')
 888 | 
 889 |             # Get bucket location for constructing the proper S3 URI
 890 |             location_response = self.s3_client.get_bucket_location(Bucket=bucket_name)
 891 |             region = location_response.get('LocationConstraint', 'us-east-1')
 892 |             if region is None:  # us-east-1 returns None
 893 |                 region = 'us-east-1'
 894 | 
 895 |             # Construct S3 URIs
 896 |             s3_uri = f's3://{bucket_name}/{s3_key}'
 897 | 
 898 |             result = 'Python code uploaded successfully!\n\n'
 899 |             result += f'S3 URI: {s3_uri}\n'
 900 |             result += f'Region: {region}\n'
 901 | 
 902 |             return UploadToS3Response(
 903 |                 isError=False,
 904 |                 content=[TextContent(type='text', text=result)],
 905 |                 s3_uri=s3_uri,
 906 |                 bucket_name=bucket_name,
 907 |                 s3_key=s3_key,
 908 |             )
 909 | 
 910 |         except ClientError as e:
 911 |             error_message = f'AWS Error: {str(e)}'
 912 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 913 |             return UploadToS3Response(
 914 |                 isError=True,
 915 |                 content=[TextContent(type='text', text=error_message)],
 916 |                 s3_uri='',
 917 |                 bucket_name=bucket_name,
 918 |                 s3_key=s3_key,
 919 |             )
 920 |         except Exception as e:
 921 |             error_message = f'Error: {str(e)}'
 922 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
 923 |             return UploadToS3Response(
 924 |                 isError=True,
 925 |                 content=[TextContent(type='text', text=error_message)],
 926 |                 s3_uri='',
 927 |                 bucket_name=bucket_name,
 928 |                 s3_key=s3_key,
 929 |             )
 930 | 
 931 |     async def analyze_s3_usage_for_data_processing(
 932 |         self,
 933 |         ctx: Context,
 934 |         bucket_name: Annotated[
 935 |             Optional[str],
 936 |             Field(
 937 |                 description='Optional specific bucket to analyze (None for all buckets)',
 938 |             ),
 939 |         ] = None,
 940 |     ) -> AnalyzeS3UsageResponse:
 941 |         """Analyze S3 bucket usage patterns for data processing services (Glue, EMR, Athena).
 942 | 
 943 |         This tool helps identify which buckets are actively used by data processing services
 944 |         and which ones might be idle or underutilized.
 945 | 
 946 |         Args:
 947 |             ctx: The MCP context
 948 |             bucket_name: Optional specific bucket to analyze (None for all buckets)
 949 | 
 950 |         Returns:
 951 |             AnalyzeS3UsageResponse: Analysis report of S3 usage patterns
 952 |         """
 953 |         try:
 954 |             log_with_request_id(
 955 |                 ctx,
 956 |                 LogLevel.INFO,
 957 |                 'Common Resource Handler - Tool: analyze_s3_usage_for_data_processing - Operation: analyze S3 usage',
 958 |             )
 959 | 
 960 |             # Create necessary clients
 961 |             glue_client = AwsHelper.create_boto3_client('glue')
 962 |             athena_client = AwsHelper.create_boto3_client('athena')
 963 |             emr_client = AwsHelper.create_boto3_client('emr')
 964 | 
 965 |             # Get buckets to analyze
 966 |             if bucket_name:
 967 |                 try:
 968 |                     # Check if specific bucket exists
 969 |                     self.s3_client.head_bucket(Bucket=bucket_name)
 970 |                     buckets = [{'Name': bucket_name}]
 971 |                 except ClientError:
 972 |                     error_message = f"Bucket '{bucket_name}' does not exist or is not accessible"
 973 |                     return AnalyzeS3UsageResponse(
 974 |                         isError=True,
 975 |                         content=[TextContent(type='text', text=error_message)],
 976 |                         analysis_summary='',
 977 |                         service_usage={},
 978 |                     )
 979 |             else:
 980 |                 # Get all buckets
 981 |                 response = self.s3_client.list_buckets()
 982 |                 buckets = response['Buckets']
 983 | 
 984 |             # Initialize result
 985 |             result = 'S3 Usage Analysis for Data Processing Services\n'
 986 |             result += f'{"=" * 50}\n\n'
 987 | 
 988 |             # Track service usage
 989 |             service_usage = {
 990 |                 'glue': [],
 991 |                 'athena': [],
 992 |                 'emr': [],
 993 |                 'idle': [],
 994 |                 'unknown': [],
 995 |             }
 996 | 
 997 |             # Analyze each bucket
 998 |             for bucket in buckets:
 999 |                 bucket_name_res: str = bucket['Name']
1000 |                 result += f'Analyzing bucket: {bucket_name_res}\n'
1001 | 
1002 |                 # Initialize bucket usage flags
1003 |                 usage = {
1004 |                     'glue': False,
1005 |                     'athena': False,
1006 |                     'emr': False,
1007 |                     'last_activity': None,
1008 |                 }
1009 | 
1010 |                 # Check Glue connections and crawlers for this bucket
1011 |                 try:
1012 |                     # Check Glue connections
1013 |                     connections = glue_client.get_connections()
1014 |                     for conn in connections.get('ConnectionList', []):
1015 |                         conn_props = conn.get('ConnectionProperties', {})
1016 |                         if 'JDBC_CONNECTION_URL' in conn_props:
1017 |                             if bucket_name_res in (conn_props['JDBC_CONNECTION_URL'] or ''):
1018 |                                 usage['glue'] = True
1019 |                                 break
1020 | 
1021 |                     # Check Glue crawlers
1022 |                     crawlers = glue_client.get_crawlers()
1023 |                     for crawler in crawlers.get('Crawlers', []):
1024 |                         targets = crawler.get('Targets', {})
1025 |                         s3_targets = targets.get('S3Targets', [])
1026 |                         for target in s3_targets:
1027 |                             target_path = target.get('Path', '') or ''
1028 |                             if bucket_name_res in target_path:
1029 |                                 usage['glue'] = True
1030 |                                 break
1031 | 
1032 |                     # Check Glue jobs
1033 |                     jobs = glue_client.get_jobs()
1034 |                     for job in jobs.get('Jobs', []):
1035 |                         if 'DefaultArguments' in job:
1036 |                             for arg_key, arg_value in job['DefaultArguments'].items():
1037 |                                 if isinstance(arg_value, str) and bucket_name_res in arg_value:
1038 |                                     usage['glue'] = True
1039 |                                     break
1040 |                 except Exception as e:
1041 |                     result += f'  Error checking Glue usage: {str(e)}\n'
1042 | 
1043 |                 # Check Athena workgroups for this bucket
1044 |                 try:
1045 |                     workgroups = athena_client.list_work_groups()
1046 |                     for wg in workgroups.get('WorkGroups', []):
1047 |                         wg_name = wg['Name']
1048 |                         try:
1049 |                             wg_config = athena_client.get_work_group(WorkGroup=wg_name)
1050 |                             output_location = (
1051 |                                 wg_config.get('WorkGroup', {})
1052 |                                 .get('Configuration', {})
1053 |                                 .get('ResultConfiguration', {})
1054 |                                 .get('OutputLocation', '')
1055 |                             )
1056 |                             if bucket_name_res in output_location:
1057 |                                 usage['athena'] = True
1058 |                                 break
1059 |                         except Exception as e:
1060 |                             # Log the specific error and continue to next workgroup
1061 |                             result += (
1062 |                                 f'    Warning: Could not check workgroup {wg_name}: {str(e)}\n'
1063 |                             )
1064 |                             continue
1065 |                 except Exception as e:
1066 |                     result += f'  Error checking Athena usage: {str(e)}\n'
1067 | 
1068 |                 # Check EMR clusters for this bucket
1069 |                 try:
1070 |                     clusters = emr_client.list_clusters(ClusterStates=['RUNNING', 'WAITING'])
1071 |                     for cluster in clusters.get('Clusters', []):
1072 |                         cluster_id = cluster['Id']
1073 |                         try:
1074 |                             cluster_info = emr_client.describe_cluster(ClusterId=cluster_id)
1075 |                             log_uri = cluster_info.get('Cluster', {}).get('LogUri', '')
1076 |                             if bucket_name_res in log_uri:
1077 |                                 usage['emr'] = True
1078 |                                 break
1079 |                         except Exception as e:
1080 |                             # Log the specific error and continue to next cluster
1081 |                             result += (
1082 |                                 f'    Warning: Could not check cluster {cluster_id}: {str(e)}\n'
1083 |                             )
1084 |                             continue
1085 |                 except Exception as e:
1086 |                     result += f'  Error checking EMR usage: {str(e)}\n'
1087 | 
1088 |                 # Get last modified date of most recent object
1089 |                 try:
1090 |                     objects_response = self.s3_client.list_objects_v2(
1091 |                         Bucket=bucket_name_res, MaxKeys=1
1092 |                     )
1093 |                     if objects_response.get('KeyCount', 0) > 0 and 'Contents' in objects_response:
1094 |                         last_modified = objects_response['Contents'][0]['LastModified']
1095 |                         usage['last_activity'] = last_modified
1096 | 
1097 |                         # Calculate idle time
1098 |                         idle_days = (
1099 |                             datetime.now().replace(tzinfo=None)
1100 |                             - last_modified.replace(tzinfo=None)
1101 |                         ).days
1102 |                         result += f'  Last activity: {last_modified.strftime("%Y-%m-%d")} ({idle_days} days ago)\n'
1103 |                     else:
1104 |                         result += '  No objects found in bucket\n'
1105 |                 except Exception as e:
1106 |                     result += f'  Error checking last activity: {str(e)}\n'
1107 | 
1108 |                 # Determine bucket category
1109 |                 if usage['glue']:
1110 |                     result += '  ✅ Used by AWS Glue\n'
1111 |                     service_usage['glue'].append(bucket_name_res)
1112 |                 if usage['athena']:
1113 |                     result += '  ✅ Used by Amazon Athena\n'
1114 |                     service_usage['athena'].append(bucket_name_res)
1115 |                 if usage['emr']:
1116 |                     result += '  ✅ Used by Amazon EMR\n'
1117 |                     service_usage['emr'].append(bucket_name_res)
1118 | 
1119 |                 if not (usage['glue'] or usage['athena'] or usage['emr']):
1120 |                     # Check bucket name for hints
1121 |                     bucket_name_lower = bucket_name_res.lower()
1122 |                     if any(keyword in bucket_name_lower for keyword in ['glue', 'etl', 'crawler']):
1123 |                         result += (
1124 |                             '  ⚠️ Likely Glue bucket (based on name) but no active usage detected\n'
1125 |                         )
1126 |                         service_usage['glue'].append(bucket_name_res)
1127 |                     elif any(keyword in bucket_name_lower for keyword in ['athena', 'query']):
1128 |                         result += '  ⚠️ Likely Athena bucket (based on name) but no active usage detected\n'
1129 |                         service_usage['athena'].append(bucket_name_res)
1130 |                     elif any(
1131 |                         keyword in bucket_name_lower for keyword in ['emr', 'hadoop', 'spark']
1132 |                     ):
1133 |                         result += (
1134 |                             '  ⚠️ Likely EMR bucket (based on name) but no active usage detected\n'
1135 |                         )
1136 |                         service_usage['emr'].append(bucket_name_res)
1137 |                     else:
1138 |                         # Check if idle (no activity for 90+ days)
1139 |                         if (
1140 |                             usage['last_activity']
1141 |                             and (
1142 |                                 datetime.now().replace(tzinfo=None)
1143 |                                 - usage['last_activity'].replace(tzinfo=None)
1144 |                             ).days
1145 |                             > 90
1146 |                         ):
1147 |                             result += '  ⚠️ IDLE: No data processing service usage detected and no activity for 90+ days\n'
1148 |                             service_usage['idle'].append(bucket_name_res)
1149 |                         else:
1150 |                             result += '  ℹ️ No data processing service usage detected\n'
1151 |                             service_usage['unknown'].append(bucket_name_res)
1152 | 
1153 |                 result += '\n'
1154 | 
1155 |             # Summary section
1156 |             result += f'\nSummary\n{"=" * 50}\n'
1157 |             result += f'Total buckets analyzed: {len(buckets)}\n\n'
1158 | 
1159 |             result += 'Glue Buckets:\n'
1160 |             for b in service_usage['glue']:
1161 |                 result += f'  - {b}\n'
1162 | 
1163 |             result += '\nAthena Buckets:\n'
1164 |             for b in service_usage['athena']:
1165 |                 result += f'  - {b}\n'
1166 | 
1167 |             result += '\nEMR Buckets:\n'
1168 |             for b in service_usage['emr']:
1169 |                 result += f'  - {b}\n'
1170 | 
1171 |             result += '\nIdle Buckets (potential cleanup candidates):\n'
1172 |             for b in service_usage['idle']:
1173 |                 result += f'  - {b}\n'
1174 | 
1175 |             return AnalyzeS3UsageResponse(
1176 |                 isError=False,
1177 |                 content=[TextContent(type='text', text=result)],
1178 |                 analysis_summary=result,
1179 |                 service_usage=service_usage,
1180 |             )
1181 | 
1182 |         except ClientError as e:
1183 |             error_message = f'AWS Error: {str(e)}'
1184 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
1185 |             return AnalyzeS3UsageResponse(
1186 |                 isError=True,
1187 |                 content=[TextContent(type='text', text=error_message)],
1188 |                 analysis_summary='',
1189 |                 service_usage={},
1190 |             )
1191 |         except Exception as e:
1192 |             error_message = f'Error: {str(e)}'
1193 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
1194 |             return AnalyzeS3UsageResponse(
1195 |                 isError=True,
1196 |                 content=[TextContent(type='text', text=error_message)],
1197 |                 analysis_summary='',
1198 |                 service_usage={},
1199 |             )
1200 | 
1201 |     # ============================================================================
1202 |     # Helper Methods
1203 |     # ============================================================================
1204 | 
1205 |     def _get_trust_relationship_for_service(self, service_type: str) -> Dict[str, Any]:
1206 |         """Get the trust relationship policy document for a specific service.
1207 | 
1208 |         Args:
1209 |             service_type: Type of data processing service (glue, emr, or athena)
1210 | 
1211 |         Returns:
1212 |             Dict[str, Any]: Trust relationship policy document
1213 |         """
1214 |         service_principals = {
1215 |             'glue': 'glue.amazonaws.com',
1216 |             'emr': 'elasticmapreduce.amazonaws.com',
1217 |             'athena': 'athena.amazonaws.com',
1218 |         }
1219 | 
1220 |         return {
1221 |             'Version': '2012-10-17',
1222 |             'Statement': [
1223 |                 {
1224 |                     'Effect': 'Allow',
1225 |                     'Principal': {'Service': service_principals[service_type]},
1226 |                     'Action': 'sts:AssumeRole',
1227 |                 }
1228 |             ],
1229 |         }
1230 | 
1231 |     def _get_managed_policies(self, ctx, role_name):
1232 |         """Get managed policies attached to a role.
1233 | 
1234 |         Args:
1235 |             ctx: The MCP context
1236 |             role_name: Name of the IAM role
1237 | 
1238 |         Returns:
1239 |             List of PolicySummary objects
1240 |         """
1241 |         managed_policies = []
1242 |         managed_policies_response = self.iam_client.list_attached_role_policies(RoleName=role_name)
1243 | 
1244 |         for policy in managed_policies_response.get('AttachedPolicies', []):
1245 |             policy_arn = policy['PolicyArn']
1246 |             policy_details = self.iam_client.get_policy(PolicyArn=policy_arn)['Policy']
1247 | 
1248 |             # Get the policy version details to get the policy document
1249 |             policy_version = None
1250 |             try:
1251 |                 policy_version_response = self.iam_client.get_policy_version(
1252 |                     PolicyArn=policy_arn,
1253 |                     VersionId=policy_details.get('DefaultVersionId', 'v1'),
1254 |                 )
1255 |                 policy_version = policy_version_response.get('PolicyVersion', {})
1256 |             except Exception as e:
1257 |                 log_with_request_id(
1258 |                     ctx, LogLevel.WARNING, f'Failed to get policy version: {str(e)}'
1259 |                 )
1260 | 
1261 |             managed_policies.append(
1262 |                 PolicySummary(
1263 |                     policy_type='Managed',
1264 |                     description=policy_details.get('Description'),
1265 |                     policy_document=(policy_version.get('Document') if policy_version else None),
1266 |                 )
1267 |             )
1268 | 
1269 |         return managed_policies
1270 | 
1271 |     def _get_inline_policies(self, ctx, role_name):
1272 |         """Get inline policies embedded in a role.
1273 | 
1274 |         Args:
1275 |             ctx: The MCP context
1276 |             role_name: Name of the IAM role
1277 | 
1278 |         Returns:
1279 |             List of PolicySummary objects
1280 |         """
1281 |         inline_policies = []
1282 |         inline_policies_response = self.iam_client.list_role_policies(RoleName=role_name)
1283 | 
1284 |         for policy_name in inline_policies_response.get('PolicyNames', []):
1285 |             policy_response = self.iam_client.get_role_policy(
1286 |                 RoleName=role_name, PolicyName=policy_name
1287 |             )
1288 | 
1289 |             inline_policies.append(
1290 |                 PolicySummary(
1291 |                     policy_type='Inline',
1292 |                     description=None,
1293 |                     policy_document=policy_response.get('PolicyDocument'),
1294 |                 )
1295 |             )
1296 | 
1297 |         return inline_policies
1298 | 
1299 |     def _create_inline_policy(self, ctx, role_name, policy_name, permissions):
1300 |         """Create a new inline policy with the specified permissions.
1301 | 
1302 |         Args:
1303 |             ctx: The MCP context
1304 |             role_name: Name of the role
1305 |             policy_name: Name of the new policy to create
1306 |             permissions: Permissions to include in the policy
1307 | 
1308 |         Returns:
1309 |             AddInlinePolicyResponse: Information about the created policy
1310 |         """
1311 |         log_with_request_id(
1312 |             ctx,
1313 |             LogLevel.INFO,
1314 |             f'Creating new inline policy {policy_name} in role {role_name}',
1315 |         )
1316 | 
1317 |         # Check if the policy already exists
1318 |         try:
1319 |             self.iam_client.get_role_policy(RoleName=role_name, PolicyName=policy_name)
1320 |             # If we get here, the policy exists
1321 |             error_message = f'Policy {policy_name} already exists in role {role_name}. Cannot modify existing policies.'
1322 |             log_with_request_id(ctx, LogLevel.ERROR, error_message)
1323 |             return AddInlinePolicyResponse(
1324 |                 isError=True,
1325 |                 content=[TextContent(type='text', text=error_message)],
1326 |                 policy_name=policy_name,
1327 |                 role_name=role_name,
1328 |                 permissions_added={},
1329 |             )
1330 |         except self.iam_client.exceptions.NoSuchEntityException:
1331 |             # Policy doesn't exist, we can create it
1332 |             pass
1333 | 
1334 |         log_with_request_id(
1335 |             ctx,
1336 |             LogLevel.INFO,
1337 |             f'Entity not present a new inline policy {policy_name} will be added to role {role_name}',
1338 |         )
1339 | 
1340 |         # Create a new policy document
1341 |         policy_document = {'Version': '2012-10-17', 'Statement': []}
1342 | 
1343 |         # Add the permissions to the policy document
1344 |         self._add_permissions_to_document(policy_document, permissions)
1345 | 
1346 |         log_with_request_id(
1347 |             ctx,
1348 |             LogLevel.INFO,
1349 |             f'policy_document added for {role_name}',
1350 |         )
1351 | 
1352 |         # Create the policy
1353 |         self.iam_client.put_role_policy(
1354 |             RoleName=role_name,
1355 |             PolicyName=policy_name,
1356 |             PolicyDocument=json.dumps(policy_document),
1357 |         )
1358 | 
1359 |         return AddInlinePolicyResponse(
1360 |             isError=False,
1361 |             content=[
1362 |                 TextContent(
1363 |                     type='text',
1364 |                     text=f'Successfully created new inline policy {policy_name} in role {role_name}',
1365 |                 )
1366 |             ],
1367 |             policy_name=policy_name,
1368 |             role_name=role_name,
1369 |             permissions_added=permissions,
1370 |         )
1371 | 
1372 |     def _get_service_principal(self, service_type: str) -> str:
1373 |         """Get the service principal for a specific service type.
1374 | 
1375 |         Args:
1376 |             service_type: Type of data processing service
1377 | 
1378 |         Returns:
1379 |             str: Service principal
1380 |         """
1381 |         # Common service principals
1382 |         service_principals = {
1383 |             'glue': 'glue.amazonaws.com',
1384 |             'emr': 'elasticmapreduce.amazonaws.com',
1385 |             'athena': 'athena.amazonaws.com',
1386 |             'lambda': 'lambda.amazonaws.com',
1387 |             'ec2': 'ec2.amazonaws.com',
1388 |             'ecs': 'ecs.amazonaws.com',
1389 |             'eks': 'eks.amazonaws.com',
1390 |             's3': 's3.amazonaws.com',
1391 |             'sagemaker': 'sagemaker.amazonaws.com',
1392 |             'cloudformation': 'cloudformation.amazonaws.com',
1393 |             'codebuild': 'codebuild.amazonaws.com',
1394 |             'codepipeline': 'codepipeline.amazonaws.com',
1395 |             'states': 'states.amazonaws.com',
1396 |         }
1397 | 
1398 |         # Return the service principal if it exists in the mapping, otherwise use the service type as is
1399 |         return service_principals.get(service_type.lower(), f'{service_type}.amazonaws.com')
1400 | 
1401 |     def _can_be_assumed_by_service(
1402 |         self, assume_role_policy_document: Dict[str, Any], service_principal: str
1403 |     ) -> bool:
1404 |         """Check if a role can be assumed by a specific service.
1405 | 
1406 |         Args:
1407 |             assume_role_policy_document: Assume role policy document
1408 |             service_principal: Service principal to check
1409 | 
1410 |         Returns:
1411 |             bool: True if the role can be assumed by the service, False otherwise
1412 |         """
1413 |         # Check if the policy document has statements
1414 |         if not assume_role_policy_document or 'Statement' not in assume_role_policy_document:
1415 |             return False
1416 | 
1417 |         # Check each statement
1418 |         for statement in assume_role_policy_document['Statement']:
1419 |             # Only process Allow statements
1420 |             if statement.get('Effect') != 'Allow':
1421 |                 continue
1422 | 
1423 |             # Check if the statement allows the sts:AssumeRole action
1424 |             action = statement.get('Action', [])
1425 |             has_assume_role_action = False
1426 | 
1427 |             if isinstance(action, str):
1428 |                 has_assume_role_action = action == 'sts:AssumeRole'
1429 |             elif isinstance(action, list):
1430 |                 has_assume_role_action = 'sts:AssumeRole' in action
1431 | 
1432 |             if not has_assume_role_action:
1433 |                 continue
1434 | 
1435 |             # Check if the statement allows the service principal
1436 |             principal = statement.get('Principal', {})
1437 |             if 'Service' in principal:
1438 |                 service = principal['Service']
1439 |                 if isinstance(service, str):
1440 |                     if service == service_principal:
1441 |                         return True
1442 |                 elif isinstance(service, list):
1443 |                     if service_principal in service:
1444 |                         return True
1445 | 
1446 |         return False
1447 | 
1448 |     def _add_permissions_to_document(self, policy_document, permissions):
1449 |         """Add permissions to a policy document.
1450 | 
1451 |         Args:
1452 |             policy_document: Policy document to modify
1453 |             permissions: Permissions to add
1454 |         """
1455 |         if isinstance(permissions, dict):
1456 |             # Single statement
1457 |             policy_document['Statement'].append(permissions)
1458 |         elif isinstance(permissions, list):
1459 |             # Multiple statements
1460 |             policy_document['Statement'].extend(permissions)
1461 | 
```
Page 548/575FirstPrevNextLast