This is page 549 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-iot-sitewise-mcp-server/awslabs/aws_iot_sitewise_mcp_server/tools/sitewise_data.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 | """AWS IoT SiteWise Data Ingestion and Retrieval Tools."""
16 |
17 | import json
18 | from ..validation import (
19 | ValidationError,
20 | check_storage_configuration_requirements,
21 | validate_asset_id,
22 | validate_max_results,
23 | validate_property_alias,
24 | validate_region,
25 | )
26 | from awslabs.aws_iot_sitewise_mcp_server.client import create_iam_client, create_sitewise_client
27 | from awslabs.aws_iot_sitewise_mcp_server.tool_metadata import tool_metadata
28 | from botocore.exceptions import ClientError
29 | from datetime import datetime
30 | from mcp.server.fastmcp.tools import Tool
31 | from pydantic import Field
32 | from pydantic.fields import FieldInfo
33 | from typing import Any, Dict, List, Optional
34 |
35 |
36 | @tool_metadata(readonly=False)
37 | def create_bulk_import_job(
38 | job_name: str = Field(
39 | ..., description='The unique name that identifies the job request (1-256 characters)'
40 | ),
41 | job_role_arn: Optional[str] = Field(
42 | None,
43 | description='The ARN of the IAM role that allows IoT SiteWise to read Amazon S3 data. If not provided, ask the user if you can use create_bulk_import_iam_role helper function to create one.',
44 | ),
45 | files: List[Dict[str, Any]] = Field(
46 | ...,
47 | description='List of files in Amazon S3 that contain your data. Each file should have "bucket", "key", and optionally "versionId" fields',
48 | ),
49 | error_report_location: Dict[str, str] = Field(
50 | ..., description='Amazon S3 destination for errors. Must have "bucket" and "prefix" fields'
51 | ),
52 | job_configuration: Dict[str, Any] = Field(
53 | ...,
54 | description='Job configuration including file format. For CSV: {"fileFormat": {"csv": {"columnNames": ["ALIAS", "ASSET_ID", ...]}}}',
55 | ),
56 | adaptive_ingestion: bool = Field(
57 | False,
58 | description='Set to true for buffered ingestion (triggers computations and notifications for data within 7 days). Set to false for historical data ingestion only',
59 | ),
60 | delete_files_after_import: bool = Field(
61 | False, description='Set to true to delete data files from S3 after successful ingestion'
62 | ),
63 | region: str = Field('us-east-1', description='AWS region'),
64 | ) -> Dict[str, Any]:
65 | """Create a bulk import job to ingest data from Amazon S3 to AWS IoT SiteWise.
66 |
67 | This function creates a bulk import job with automatic validation of storage configuration
68 | requirements based on the adaptive_ingestion setting.
69 |
70 | When adaptive_ingestion is True, the job ingests new data and calculates metrics, transforms,
71 | and supports notifications for data with timestamps within seven days. No additional storage
72 | configuration is required.
73 |
74 | When adaptive_ingestion is False, the job performs historical data ingestion only and requires
75 | multilayer storage or warm tier to be enabled. The function automatically validates that the
76 | current storage configuration supports historical data ingestion.
77 |
78 | If job_role_arn is not provided, use the create_bulk_import_iam_role helper function to create
79 | an IAM role with the necessary S3 permissions for the data and error buckets.
80 |
81 | Args:
82 | job_name: Unique name for the job (1-256 characters, no control characters)
83 | job_role_arn: IAM role ARN that allows IoT SiteWise to read S3 data (optional - ask the user if you can use create_bulk_import_iam_role helper function to create one.)
84 | files: List of S3 file objects with bucket, key, and optional versionId. Ask the user to provide this if not included.
85 | error_report_location: S3 location for error reports (bucket and prefix). Ask the user to provide this if not included.
86 | job_configuration: Configuration including file format (CSV or Parquet). Ask the user to provide the column headers if it is a CSV file.
87 | adaptive_ingestion: Enable buffered ingestion mode. When False, requires multilayer storage or warm tier to be configured. Ask the user to provide this if not included.
88 | delete_files_after_import: Delete S3 files after ingestion (default: False)
89 | region: AWS region (default: us-east-1)
90 |
91 | Returns:
92 | Dictionary containing job creation response with jobId, jobName, and jobStatus
93 |
94 | Example:
95 | files = [{"bucket": "my-data-bucket", "key": "data/timeseries.csv"}]
96 | error_location = {"bucket": "my-error-bucket", "prefix": "errors/"}
97 | job_config = {
98 | "fileFormat": {
99 | "csv": {
100 | "columnNames": ["ALIAS", "TIMESTAMP_SECONDS", "VALUE", "QUALITY"]
101 | }
102 | }
103 | }
104 |
105 | result = create_bulk_import_job(
106 | job_name="my-buffered-ingestion-job",
107 | job_role_arn="arn:aws:iam::123456789012:role/IoTSiteWiseRole",
108 | files=files,
109 | error_report_location=error_location,
110 | job_configuration=job_config,
111 | adaptive_ingestion=True
112 | )
113 | """
114 | try:
115 | # Validate parameters
116 | if not isinstance(region, FieldInfo):
117 | validate_region(region)
118 |
119 | # Validate job name
120 | if not job_name or len(job_name) < 1 or len(job_name) > 256:
121 | raise ValidationError('Job name must be between 1 and 256 characters')
122 |
123 | # Basic validation for control characters in job name
124 | if any(ord(c) < 32 or ord(c) == 127 for c in job_name):
125 | raise ValidationError('Job name cannot contain control characters')
126 |
127 | # Validate job role ARN format
128 | if not job_role_arn:
129 | raise ValidationError(
130 | 'Job role ARN is required. I can help you create one - please ask me to create an IAM role with the necessary S3 permissions for your data and error buckets.'
131 | )
132 |
133 | if len(job_role_arn) < 1 or len(job_role_arn) > 1600:
134 | raise ValidationError('Job role ARN must be between 1 and 1600 characters')
135 |
136 | if not job_role_arn.startswith('arn:aws'):
137 | raise ValidationError('Job role ARN must be a valid AWS ARN')
138 |
139 | # Validate files list
140 | if not files or not isinstance(files, list):
141 | raise ValidationError('Files must be a non-empty list')
142 |
143 | for file_obj in files:
144 | if not isinstance(file_obj, dict):
145 | raise ValidationError('Each file must be a dictionary')
146 | if 'bucket' not in file_obj or 'key' not in file_obj:
147 | raise ValidationError('Each file must have "bucket" and "key" fields')
148 | if len(file_obj['bucket']) < 3 or len(file_obj['bucket']) > 63:
149 | raise ValidationError('S3 bucket name must be between 3 and 63 characters')
150 |
151 | # Validate error report location
152 | if not isinstance(error_report_location, dict):
153 | raise ValidationError('Error report location must be a dictionary')
154 | if 'bucket' not in error_report_location or 'prefix' not in error_report_location:
155 | raise ValidationError('Error report location must have "bucket" and "prefix" fields')
156 | if len(error_report_location['bucket']) < 3 or len(error_report_location['bucket']) > 63:
157 | raise ValidationError('Error report bucket name must be between 3 and 63 characters')
158 | if not error_report_location['prefix'].endswith('/'):
159 | raise ValidationError('Error report prefix must end with a forward slash (/)')
160 |
161 | # Validate job configuration
162 | if not isinstance(job_configuration, dict):
163 | raise ValidationError('Job configuration must be a dictionary')
164 | if 'fileFormat' not in job_configuration:
165 | raise ValidationError('Job configuration must have "fileFormat" field')
166 |
167 | file_format = job_configuration['fileFormat']
168 | if not isinstance(file_format, dict):
169 | raise ValidationError('File format must be a dictionary')
170 |
171 | # Validate CSV or Parquet format
172 | if 'csv' in file_format:
173 | csv_config = file_format['csv']
174 | if not isinstance(csv_config, dict) or 'columnNames' not in csv_config:
175 | raise ValidationError('CSV configuration must have "columnNames" field')
176 | if not isinstance(csv_config['columnNames'], list) or not csv_config['columnNames']:
177 | raise ValidationError('CSV columnNames must be a non-empty list')
178 |
179 | # Validate column names are from allowed set
180 | valid_columns = {
181 | 'ASSET_ID',
182 | 'ALIAS',
183 | 'PROPERTY_ID',
184 | 'DATA_TYPE',
185 | 'TIMESTAMP_SECONDS',
186 | 'TIMESTAMP_NANO_OFFSET',
187 | 'QUALITY',
188 | 'VALUE',
189 | }
190 | for col in csv_config['columnNames']:
191 | if col not in valid_columns:
192 | raise ValidationError(
193 | f'Invalid column name: {col}. Must be one of: {", ".join(valid_columns)}'
194 | )
195 |
196 | # Validate required columns are present
197 | required_columns = {'TIMESTAMP_SECONDS', 'VALUE', 'DATA_TYPE'}
198 | has_asset_id = 'ASSET_ID' in csv_config['columnNames']
199 | has_property_id = 'PROPERTY_ID' in csv_config['columnNames']
200 | has_alias = 'ALIAS' in csv_config['columnNames']
201 |
202 | # Must have either (ASSET_ID + PROPERTY_ID) OR ALIAS, but not all three
203 | if has_asset_id and has_property_id and has_alias:
204 | raise ValidationError(
205 | 'CSV cannot include ASSET_ID, PROPERTY_ID, and ALIAS together'
206 | )
207 | elif has_asset_id and not has_property_id:
208 | raise ValidationError('CSV with ASSET_ID must also include PROPERTY_ID')
209 | elif has_property_id and not has_asset_id:
210 | raise ValidationError('CSV with PROPERTY_ID must also include ASSET_ID')
211 | elif not (has_alias or (has_asset_id and has_property_id)):
212 | raise ValidationError(
213 | 'CSV must include either ALIAS or both ASSET_ID and PROPERTY_ID'
214 | )
215 |
216 | missing_required = required_columns - set(csv_config['columnNames'])
217 | if missing_required:
218 | raise ValidationError(
219 | f'CSV missing required columns: {", ".join(missing_required)}'
220 | )
221 | elif 'parquet' not in file_format:
222 | raise ValidationError('File format must specify either "csv" or "parquet"')
223 |
224 | client = create_sitewise_client(region)
225 |
226 | # Validate adaptive_ingestion is provided
227 | if not isinstance(adaptive_ingestion, bool):
228 | raise ValidationError('Please provide a boolean value for adaptive_ingestion')
229 |
230 | # Validate storage configuration requirements based on adaptive_ingestion setting
231 | check_storage_configuration_requirements(client, adaptive_ingestion)
232 |
233 | # Build the API parameters
234 | params = {
235 | 'jobName': job_name,
236 | 'jobRoleArn': job_role_arn,
237 | 'files': files,
238 | 'errorReportLocation': error_report_location,
239 | 'jobConfiguration': job_configuration,
240 | 'adaptiveIngestion': adaptive_ingestion,
241 | 'deleteFilesAfterImport': delete_files_after_import,
242 | }
243 |
244 | response = client.create_bulk_import_job(**params)
245 |
246 | return {
247 | 'success': True,
248 | 'job_id': response['jobId'],
249 | 'job_name': response['jobName'],
250 | 'job_status': response['jobStatus'],
251 | }
252 |
253 | except ValidationError as e:
254 | return {
255 | 'success': False,
256 | 'error': f'Validation error: {str(e)}',
257 | 'error_code': 'ValidationException',
258 | }
259 | except ClientError as e:
260 | return {
261 | 'success': False,
262 | 'error': str(e),
263 | 'error_code': e.response['Error']['Code'],
264 | }
265 |
266 |
267 | @tool_metadata(readonly=False)
268 | def create_buffered_ingestion_job(
269 | job_name: str = Field(
270 | ..., description='The unique name that identifies the job request (1-256 characters)'
271 | ),
272 | job_role_arn: str = Field(
273 | ..., description='The ARN of the IAM role that allows IoT SiteWise to read Amazon S3 data'
274 | ),
275 | files: List[Dict[str, Any]] = Field(
276 | ...,
277 | description='List of files in Amazon S3 that contain your data. Each file should have "bucket", "key", and optionally "versionId" fields',
278 | ),
279 | error_report_location: Dict[str, str] = Field(
280 | ..., description='Amazon S3 destination for errors. Must have "bucket" and "prefix" fields'
281 | ),
282 | job_configuration: Dict[str, Any] = Field(
283 | ...,
284 | description='Job configuration including file format. For CSV: {"fileFormat": {"csv": {"columnNames": ["ALIAS", "ASSET_ID", ...]}}}',
285 | ),
286 | delete_files_after_import: bool = Field(
287 | False, description='Set to true to delete data files from S3 after successful ingestion'
288 | ),
289 | region: str = Field('us-east-1', description='AWS region'),
290 | ) -> Dict[str, Any]:
291 | """Create a buffered ingestion job to ingest data from Amazon S3 to AWS IoT SiteWise.
292 |
293 | This is a convenience function that calls create_bulk_import_job with adaptive_ingestion=True
294 | to enable buffered ingestion mode for real-time processing of recent data (within 30 days).
295 |
296 | Args:
297 | job_name: Unique name for the job (1-256 characters, no control characters)
298 | job_role_arn: IAM role ARN that allows IoT SiteWise to read S3 data (optional - ask the user if you can use create_bulk_import_iam_role helper function to create one.)
299 | files: List of S3 file objects with bucket, key, and optional versionId
300 | error_report_location: S3 location for error reports (bucket and prefix)
301 | job_configuration: Configuration including file format (CSV or Parquet)
302 | delete_files_after_import: Delete S3 files after ingestion (default: False)
303 | region: AWS region (default: us-east-1)
304 |
305 | Returns:
306 | Dictionary containing job creation response with jobId, jobName, and jobStatus
307 |
308 | Example:
309 | files = [{"bucket": "my-data-bucket", "key": "data/timeseries.csv"}]
310 | error_location = {"bucket": "my-error-bucket", "prefix": "errors/"}
311 | job_config = {
312 | "fileFormat": {
313 | "csv": {
314 | "columnNames": ["ALIAS", "TIMESTAMP_SECONDS", "VALUE", "QUALITY"]
315 | }
316 | }
317 | }
318 |
319 | result = create_buffered_ingestion_job(
320 | job_name="my-buffered-ingestion-job",
321 | job_role_arn="arn:aws:iam::123456789012:role/IoTSiteWiseRole",
322 | files=files,
323 | error_report_location=error_location,
324 | job_configuration=job_config
325 | )
326 | """
327 | # Call the general create_bulk_import_job function with adaptive_ingestion=True
328 | return create_bulk_import_job(
329 | job_name=job_name,
330 | job_role_arn=job_role_arn,
331 | files=files,
332 | error_report_location=error_report_location,
333 | job_configuration=job_configuration,
334 | adaptive_ingestion=True, # Always set to True for buffered ingestion
335 | delete_files_after_import=delete_files_after_import,
336 | region=region,
337 | )
338 |
339 |
340 | @tool_metadata(readonly=False)
341 | def batch_put_asset_property_value(
342 | entries: List[Dict[str, Any]] = Field(
343 | ..., description='List of asset property value entries to send to AWS IoT SiteWise'
344 | ),
345 | region: str = Field('us-east-1', description='AWS region'),
346 | ) -> Dict[str, Any]:
347 | """Send a list of asset property values to AWS IoT SiteWise.
348 |
349 | Args:
350 | entries: The list of asset property value entries to send to AWS IoT SiteWise
351 | region: AWS region (default: us-east-1)
352 |
353 | Returns:
354 | Dictionary containing batch put response
355 | """
356 | try:
357 | client = create_sitewise_client(region)
358 |
359 | response = client.batch_put_asset_property_value(entries=entries)
360 |
361 | return {'success': True, 'error_entries': response.get('errorEntries', [])}
362 |
363 | except ClientError as e:
364 | return {
365 | 'success': False,
366 | 'error': str(e),
367 | 'error_code': e.response['Error']['Code'],
368 | }
369 |
370 |
371 | @tool_metadata(readonly=True)
372 | def get_asset_property_value(
373 | asset_id: Optional[str] = Field(None, description='The ID of the asset'),
374 | property_id: Optional[str] = Field(None, description='The ID of the asset property'),
375 | property_alias: Optional[str] = Field(
376 | None, description='The alias that identifies the property'
377 | ),
378 | region: str = Field('us-east-1', description='AWS region'),
379 | ) -> Dict[str, Any]:
380 | """Get the current value for the given asset property.
381 |
382 | Args:
383 | asset_id: The ID of the asset
384 | property_id: The ID of the asset property
385 | property_alias: The alias that identifies the property
386 | region: AWS region (default: us-east-1)
387 |
388 | Returns:
389 | Dictionary containing current property value
390 | """
391 | try:
392 | # Validate parameters
393 | if not isinstance(region, FieldInfo):
394 | validate_region(region)
395 | if asset_id and not isinstance(asset_id, FieldInfo):
396 | validate_asset_id(asset_id)
397 | if property_alias and not isinstance(property_alias, FieldInfo):
398 | validate_property_alias(property_alias)
399 |
400 | client = create_sitewise_client(region)
401 |
402 | params: Dict[str, Any] = {}
403 | if asset_id:
404 | params['assetId'] = asset_id
405 | if property_id:
406 | params['propertyId'] = property_id
407 | if property_alias:
408 | params['propertyAlias'] = property_alias
409 |
410 | response = client.get_asset_property_value(**params)
411 |
412 | property_value = response['propertyValue']
413 | return {
414 | 'success': True,
415 | 'value': property_value['value'],
416 | 'timestamp': property_value['timestamp'],
417 | 'quality': property_value.get('quality', 'GOOD'),
418 | }
419 |
420 | except ClientError as e:
421 | return {
422 | 'success': False,
423 | 'error': str(e),
424 | 'error_code': e.response['Error']['Code'],
425 | }
426 |
427 |
428 | @tool_metadata(readonly=True)
429 | def get_asset_property_value_history(
430 | asset_id: Optional[str] = Field(None, description='The ID of the asset'),
431 | property_id: Optional[str] = Field(None, description='The ID of the asset property'),
432 | property_alias: Optional[str] = Field(
433 | None, description='The alias that identifies the property'
434 | ),
435 | start_date: Optional[str] = Field(
436 | None, description='The exclusive start of the range (ISO 8601 format)'
437 | ),
438 | end_date: Optional[str] = Field(
439 | None, description='The inclusive end of the range (ISO 8601 format)'
440 | ),
441 | qualities: Optional[List[str]] = Field(
442 | None, description='The quality by which to filter asset data (GOOD, BAD, UNCERTAIN)'
443 | ),
444 | time_ordering: str = Field(
445 | 'ASCENDING', description='The chronological sorting order (ASCENDING, DESCENDING)'
446 | ),
447 | next_token: Optional[str] = Field(
448 | None, description='The token to be used for the next set of paginated results'
449 | ),
450 | max_results: int = Field(100, description='The maximum number of results to return (1-4000)'),
451 | region: str = Field('us-east-1', description='AWS region'),
452 | ) -> Dict[str, Any]:
453 | """Get the history of an asset property's values.
454 |
455 | Args:
456 | asset_id: The ID of the asset
457 | property_id: The ID of the asset property
458 | property_alias: The alias that identifies the property
459 | start_date: The exclusive start of the range (ISO 8601 format)
460 | end_date: The inclusive end of the range (ISO 8601 format)
461 | qualities: The quality by which to filter asset data (GOOD, BAD, UNCERTAIN)
462 | time_ordering: The chronological sorting order of the requested information \
463 | (ASCENDING, DESCENDING)
464 | next_token: The token to be used for the next set of paginated results
465 | max_results: The maximum number of results to return (1-4000, default: 100)
466 | region: AWS region (default: us-east-1)
467 |
468 | Returns:
469 | Dictionary containing property value history
470 | """
471 | try:
472 | # Validate parameters
473 | if not isinstance(region, FieldInfo):
474 | validate_region(region)
475 | if not isinstance(max_results, FieldInfo):
476 | validate_max_results(max_results, min_val=1, max_val=4000)
477 | if asset_id and not isinstance(asset_id, FieldInfo):
478 | validate_asset_id(asset_id)
479 | if property_alias and not isinstance(property_alias, FieldInfo):
480 | validate_property_alias(property_alias)
481 |
482 | client = create_sitewise_client(region)
483 |
484 | params: Dict[str, Any] = {
485 | 'timeOrdering': time_ordering,
486 | 'maxResults': max_results,
487 | }
488 |
489 | if asset_id:
490 | params['assetId'] = asset_id
491 | if property_id:
492 | params['propertyId'] = property_id
493 | if property_alias:
494 | params['propertyAlias'] = property_alias
495 | if start_date:
496 | params['startDate'] = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
497 | if end_date:
498 | params['endDate'] = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
499 | if qualities:
500 | params['qualities'] = qualities
501 | if next_token:
502 | params['nextToken'] = next_token
503 |
504 | response = client.get_asset_property_value_history(**params)
505 |
506 | return {
507 | 'success': True,
508 | 'asset_property_value_history': response['assetPropertyValueHistory'],
509 | 'next_token': response.get('nextToken', ''),
510 | }
511 |
512 | except ClientError as e:
513 | return {
514 | 'success': False,
515 | 'error': str(e),
516 | 'error_code': e.response['Error']['Code'],
517 | }
518 |
519 |
520 | @tool_metadata(readonly=True)
521 | def get_asset_property_aggregates(
522 | asset_id: Optional[str] = Field(None, description='The ID of the asset'),
523 | property_id: Optional[str] = Field(None, description='The ID of the asset property'),
524 | property_alias: Optional[str] = Field(
525 | None, description='The alias that identifies the property'
526 | ),
527 | aggregate_types: Optional[List[str]] = Field(
528 | None,
529 | description='The data aggregating function (AVERAGE, COUNT, MAXIMUM, MINIMUM, SUM, STANDARD_DEVIATION)',
530 | ),
531 | resolution: str = Field('1h', description='The time interval over which to aggregate data'),
532 | start_date: Optional[str] = Field(
533 | None, description='The exclusive start of the range (ISO 8601 format)'
534 | ),
535 | end_date: Optional[str] = Field(
536 | None, description='The inclusive end of the range (ISO 8601 format)'
537 | ),
538 | qualities: Optional[List[str]] = Field(
539 | None, description='The quality by which to filter asset data (GOOD, BAD, UNCERTAIN)'
540 | ),
541 | time_ordering: str = Field(
542 | 'ASCENDING', description='The chronological sorting order (ASCENDING, DESCENDING)'
543 | ),
544 | next_token: Optional[str] = Field(
545 | None, description='The token to be used for the next set of paginated results'
546 | ),
547 | max_results: int = Field(100, description='The maximum number of results to return (1-4000)'),
548 | region: str = Field('us-east-1', description='AWS region'),
549 | ) -> Dict[str, Any]:
550 | """Get aggregated values for an asset property.
551 |
552 | Args:
553 | asset_id: The ID of the asset
554 | property_id: The ID of the asset property
555 | property_alias: The alias that identifies the property
556 | aggregate_types: The data aggregating function (AVERAGE, COUNT, MAXIMUM, \
557 | MINIMUM, SUM, STANDARD_DEVIATION)
558 | resolution: The time interval over which to aggregate data
559 | start_date: The exclusive start of the range (ISO 8601 format)
560 | end_date: The inclusive end of the range (ISO 8601 format)
561 | qualities: The quality by which to filter asset data (GOOD, BAD, UNCERTAIN)
562 | time_ordering: The chronological sorting order of the requested information \
563 | (ASCENDING, DESCENDING)
564 | next_token: The token to be used for the next set of paginated results
565 | max_results: The maximum number of results to return (1-4000, default: 100)
566 | region: AWS region (default: us-east-1)
567 |
568 | Returns:
569 | Dictionary containing property aggregates
570 | """
571 | try:
572 | # Validate parameters
573 | if not isinstance(region, FieldInfo):
574 | validate_region(region)
575 | if not isinstance(max_results, FieldInfo):
576 | validate_max_results(max_results, min_val=1, max_val=4000)
577 | if asset_id and not isinstance(asset_id, FieldInfo):
578 | validate_asset_id(asset_id)
579 | if property_alias and not isinstance(property_alias, FieldInfo):
580 | validate_property_alias(property_alias)
581 |
582 | client = create_sitewise_client(region)
583 |
584 | if not aggregate_types:
585 | aggregate_types = ['AVERAGE']
586 |
587 | params: Dict[str, Any] = {
588 | 'aggregateTypes': aggregate_types,
589 | 'resolution': resolution,
590 | 'timeOrdering': time_ordering,
591 | 'maxResults': max_results,
592 | }
593 |
594 | if asset_id:
595 | params['assetId'] = asset_id
596 | if property_id:
597 | params['propertyId'] = property_id
598 | if property_alias:
599 | params['propertyAlias'] = property_alias
600 | if start_date:
601 | params['startDate'] = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
602 | if end_date:
603 | params['endDate'] = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
604 | if qualities:
605 | params['qualities'] = qualities
606 | if next_token:
607 | params['nextToken'] = next_token
608 |
609 | response = client.get_asset_property_aggregates(**params)
610 |
611 | return {
612 | 'success': True,
613 | 'aggregated_values': response['aggregatedValues'],
614 | 'next_token': response.get('nextToken', ''),
615 | }
616 |
617 | except ClientError as e:
618 | return {
619 | 'success': False,
620 | 'error': str(e),
621 | 'error_code': e.response['Error']['Code'],
622 | }
623 |
624 |
625 | @tool_metadata(readonly=True)
626 | def get_interpolated_asset_property_values(
627 | asset_id: Optional[str] = Field(None, description='The ID of the asset'),
628 | property_id: Optional[str] = Field(None, description='The ID of the asset property'),
629 | property_alias: Optional[str] = Field(
630 | None, description='The alias that identifies the property'
631 | ),
632 | start_time_in_seconds: Optional[int] = Field(
633 | None, description='The exclusive start of the range (Unix epoch time in seconds)'
634 | ),
635 | end_time_in_seconds: Optional[int] = Field(
636 | None, description='The inclusive end of the range (Unix epoch time in seconds)'
637 | ),
638 | quality: str = Field(
639 | 'GOOD', description='The quality of the asset property value (GOOD, BAD, UNCERTAIN)'
640 | ),
641 | interval_in_seconds: int = Field(
642 | 3600, description='The time interval in seconds over which to interpolate data'
643 | ),
644 | next_token: Optional[str] = Field(
645 | None, description='The token to be used for the next set of paginated results'
646 | ),
647 | max_results: int = Field(100, description='The maximum number of results to return (1-250)'),
648 | interpolation_type: str = Field(
649 | 'LINEAR_INTERPOLATION',
650 | description='The interpolation type (LINEAR_INTERPOLATION, LOCF_INTERPOLATION)',
651 | ),
652 | interval_window_in_seconds: Optional[int] = Field(
653 | None, description='The query interval for interpolated values'
654 | ),
655 | region: str = Field('us-east-1', description='AWS region'),
656 | ) -> Dict[str, Any]:
657 | """Get interpolated values for an asset property for a specified time interval.
658 |
659 | Args:
660 | asset_id: The ID of the asset
661 | property_id: The ID of the asset property
662 | property_alias: The alias that identifies the property
663 | start_time_in_seconds: The exclusive start of the range (Unix epoch \
664 | time in seconds)
665 | end_time_in_seconds: The inclusive end of the range (Unix epoch time \
666 | in seconds)
667 | quality: The quality of the asset property value (GOOD, BAD, UNCERTAIN)
668 | interval_in_seconds: The time interval in seconds over which to \
669 | interpolate data
670 | next_token: The token to be used for the next set of paginated results
671 | max_results: The maximum number of results to return (1-4000, default: 100)
672 | interpolation_type: The interpolation type (LINEAR_INTERPOLATION, \
673 | LOCF_INTERPOLATION)
674 | interval_window_in_seconds: The query interval for the window
675 | region: AWS region (default: us-east-1)
676 |
677 | Returns:
678 | Dictionary containing interpolated property values
679 | """
680 | try:
681 | # Validate parameters
682 | if not isinstance(region, FieldInfo):
683 | validate_region(region)
684 | if not isinstance(max_results, FieldInfo):
685 | validate_max_results(max_results, min_val=1, max_val=250)
686 | if asset_id and not isinstance(asset_id, FieldInfo):
687 | validate_asset_id(asset_id)
688 | if property_alias and not isinstance(property_alias, FieldInfo):
689 | validate_property_alias(property_alias)
690 |
691 | client = create_sitewise_client(region)
692 |
693 | params: Dict[str, Any] = {
694 | 'startTimeInSeconds': start_time_in_seconds,
695 | 'endTimeInSeconds': end_time_in_seconds,
696 | 'quality': quality,
697 | 'intervalInSeconds': interval_in_seconds,
698 | 'maxResults': max_results,
699 | 'type': interpolation_type,
700 | }
701 |
702 | if asset_id:
703 | params['assetId'] = asset_id
704 | if property_id:
705 | params['propertyId'] = property_id
706 | if property_alias:
707 | params['propertyAlias'] = property_alias
708 | if next_token:
709 | params['nextToken'] = next_token
710 | if interval_window_in_seconds:
711 | params['intervalWindowInSeconds'] = interval_window_in_seconds
712 |
713 | response = client.get_interpolated_asset_property_values(**params)
714 |
715 | return {
716 | 'success': True,
717 | 'interpolated_asset_property_values': response['interpolatedAssetPropertyValues'],
718 | 'next_token': response.get('nextToken', ''),
719 | }
720 |
721 | except ClientError as e:
722 | return {
723 | 'success': False,
724 | 'error': str(e),
725 | 'error_code': e.response['Error']['Code'],
726 | }
727 |
728 |
729 | @tool_metadata(readonly=True)
730 | def batch_get_asset_property_value(
731 | entries: List[Dict[str, Any]] = Field(
732 | ..., description='The list of asset property identifiers for the batch get request'
733 | ),
734 | next_token: Optional[str] = Field(
735 | None, description='The token to be used for the next set of paginated results'
736 | ),
737 | region: str = Field('us-east-1', description='AWS region'),
738 | ) -> Dict[str, Any]:
739 | """Get the current values for multiple asset properties.
740 |
741 | Args:
742 | entries: The list of asset property identifiers for the batch get request
743 | next_token: The token to be used for the next set of paginated results
744 | region: AWS region (default: us-east-1)
745 |
746 | Returns:
747 | Dictionary containing batch get response
748 | """
749 | try:
750 | client = create_sitewise_client(region)
751 |
752 | params: Dict[str, Any] = {'entries': entries}
753 | if next_token:
754 | params['nextToken'] = next_token
755 |
756 | response = client.batch_get_asset_property_value(**params)
757 |
758 | return {
759 | 'success': True,
760 | 'success_entries': response.get('successEntries', []),
761 | 'skipped_entries': response.get('skippedEntries', []),
762 | 'error_entries': response.get('errorEntries', []),
763 | 'next_token': response.get('nextToken', ''),
764 | }
765 |
766 | except ClientError as e:
767 | return {
768 | 'success': False,
769 | 'error': str(e),
770 | 'error_code': e.response['Error']['Code'],
771 | }
772 |
773 |
774 | @tool_metadata(readonly=True)
775 | def batch_get_asset_property_value_history(
776 | entries: List[Dict[str, Any]] = Field(
777 | ...,
778 | description='The list of asset property historical value entries for the batch get request',
779 | ),
780 | next_token: Optional[str] = Field(
781 | None, description='The token to be used for the next set of paginated results'
782 | ),
783 | max_results: int = Field(100, description='The maximum number of results to return (1-4000)'),
784 | region: str = Field('us-east-1', description='AWS region'),
785 | ) -> Dict[str, Any]:
786 | """Get the historical values for multiple asset properties.
787 |
788 | Args:
789 | entries: The list of asset property historical value entries for the \
790 | batch get request
791 | next_token: The token to be used for the next set of paginated results
792 | max_results: The maximum number of results to return (1-4000, default: 100)
793 | region: AWS region (default: us-east-1)
794 |
795 | Returns:
796 | Dictionary containing batch get history response
797 | """
798 | try:
799 | client = create_sitewise_client(region)
800 |
801 | params: Dict[str, Any] = {'entries': entries, 'maxResults': max_results}
802 | if next_token:
803 | params['nextToken'] = next_token
804 |
805 | response = client.batch_get_asset_property_value_history(**params)
806 |
807 | return {
808 | 'success': True,
809 | 'success_entries': response.get('successEntries', []),
810 | 'skipped_entries': response.get('skippedEntries', []),
811 | 'error_entries': response.get('errorEntries', []),
812 | 'next_token': response.get('nextToken', ''),
813 | }
814 |
815 | except ClientError as e:
816 | return {
817 | 'success': False,
818 | 'error': str(e),
819 | 'error_code': e.response['Error']['Code'],
820 | }
821 |
822 |
823 | @tool_metadata(readonly=True)
824 | def batch_get_asset_property_aggregates(
825 | entries: List[Dict[str, Any]] = Field(
826 | ..., description='The list of asset property aggregate entries for the batch get request'
827 | ),
828 | next_token: Optional[str] = Field(
829 | None, description='The token to be used for the next set of paginated results'
830 | ),
831 | max_results: int = Field(100, description='The maximum number of results to return (1-4000)'),
832 | region: str = Field('us-east-1', description='AWS region'),
833 | ) -> Dict[str, Any]:
834 | """Get aggregated values for multiple asset properties.
835 |
836 | Args:
837 | entries: The list of asset property aggregate entries for the batch get request
838 | next_token: The token to be used for the next set of paginated results
839 | max_results: The maximum number of results to return (1-4000, default: 100)
840 | region: AWS region (default: us-east-1)
841 |
842 | Returns:
843 | Dictionary containing batch get aggregates response
844 | """
845 | try:
846 | client = create_sitewise_client(region)
847 |
848 | params: Dict[str, Any] = {'entries': entries, 'maxResults': max_results}
849 | if next_token:
850 | params['nextToken'] = next_token
851 |
852 | response = client.batch_get_asset_property_aggregates(**params)
853 |
854 | return {
855 | 'success': True,
856 | 'success_entries': response.get('successEntries', []),
857 | 'skipped_entries': response.get('skippedEntries', []),
858 | 'error_entries': response.get('errorEntries', []),
859 | 'next_token': response.get('nextToken', ''),
860 | }
861 |
862 | except ClientError as e:
863 | return {
864 | 'success': False,
865 | 'error': str(e),
866 | 'error_code': e.response['Error']['Code'],
867 | }
868 |
869 |
870 | @tool_metadata(readonly=True)
871 | def list_bulk_import_jobs(
872 | filter: Optional[str] = Field(
873 | None,
874 | description='Filter to apply to the list of bulk import jobs. Valid values: ALL, PENDING, RUNNING, CANCELLED, FAILED, COMPLETED_WITH_FAILURES, COMPLETED',
875 | ),
876 | next_token: Optional[str] = Field(
877 | None, description='The token to be used for the next set of paginated results'
878 | ),
879 | max_results: int = Field(50, description='The maximum number of results to return (1-250)'),
880 | region: str = Field('us-east-1', description='AWS region'),
881 | ) -> Dict[str, Any]:
882 | """List bulk import jobs in AWS IoT SiteWise.
883 |
884 | This function retrieves a paginated list of bulk import job summaries with optional filtering
885 | by job status. Each job summary includes basic information like job ID, name, status, and timestamps.
886 |
887 | Args:
888 | filter: Optional filter to apply to the list. Valid values:
889 | - ALL: List all jobs (default)
890 | - PENDING: Jobs waiting to start
891 | - RUNNING: Jobs currently executing
892 | - CANCELLED: Jobs that were cancelled
893 | - FAILED: Jobs that failed
894 | - COMPLETED_WITH_FAILURES: Jobs completed but with some failures
895 | - COMPLETED: Jobs that completed successfully
896 | next_token: Token for paginated results
897 | max_results: Maximum number of results to return (1-250, default: 25)
898 | region: AWS region (default: us-east-1)
899 |
900 | Returns:
901 | Dictionary containing:
902 | - success: Boolean indicating operation success
903 | - job_summaries: List of job summary objects
904 | - next_token: Token for next page (if applicable)
905 |
906 | Example:
907 | # List all bulk import jobs
908 | result = list_bulk_import_jobs()
909 |
910 | # List only running jobs
911 | result = list_bulk_import_jobs(filter="RUNNING")
912 |
913 | # List with pagination
914 | result = list_bulk_import_jobs(max_results=10, next_token="...")
915 | """
916 | try:
917 | # Validate parameters
918 | if not isinstance(region, FieldInfo):
919 | validate_region(region)
920 | if not isinstance(max_results, FieldInfo):
921 | validate_max_results(max_results, min_val=1, max_val=250)
922 |
923 | # Validate filter parameter
924 | valid_filters = {
925 | 'ALL',
926 | 'PENDING',
927 | 'RUNNING',
928 | 'CANCELLED',
929 | 'FAILED',
930 | 'COMPLETED_WITH_FAILURES',
931 | 'COMPLETED',
932 | }
933 | if not isinstance(filter, FieldInfo) and filter and filter not in valid_filters:
934 | raise ValidationError(
935 | f'Invalid filter: {filter}. Must be one of: {", ".join(valid_filters)}'
936 | )
937 |
938 | client = create_sitewise_client(region)
939 |
940 | params: Dict[str, Any] = {
941 | 'maxResults': max_results,
942 | }
943 |
944 | if filter:
945 | params['filter'] = filter
946 | if next_token:
947 | params['nextToken'] = next_token
948 |
949 | response = client.list_bulk_import_jobs(**params)
950 |
951 | return {
952 | 'success': True,
953 | 'job_summaries': response.get('jobSummaries', []),
954 | 'next_token': response.get('nextToken', ''),
955 | }
956 |
957 | except ValidationError as e:
958 | return {
959 | 'success': False,
960 | 'error': f'Validation error: {str(e)}',
961 | 'error_code': 'ValidationException',
962 | }
963 | except ClientError as e:
964 | return {
965 | 'success': False,
966 | 'error': str(e),
967 | 'error_code': e.response['Error']['Code'],
968 | }
969 |
970 |
971 | @tool_metadata(readonly=True)
972 | def describe_bulk_import_job(
973 | job_id: str = Field(
974 | ..., description='The ID of the bulk import job to describe (UUID format)'
975 | ),
976 | region: str = Field('us-east-1', description='AWS region'),
977 | ) -> Dict[str, Any]:
978 | """Get detailed information about a specific bulk import job in AWS IoT SiteWise.
979 |
980 | This function retrieves comprehensive details about a bulk import job including its configuration,
981 | status, progress, error information, and execution statistics.
982 |
983 | Args:
984 | job_id: The unique identifier of the bulk import job (UUID format)
985 | region: AWS region (default: us-east-1)
986 |
987 | Returns:
988 | Dictionary containing:
989 | - success: Boolean indicating operation success
990 | - job_id: The job identifier
991 | - job_name: The job name
992 | - job_status: Current status of the job
993 | - job_role_arn: IAM role ARN used by the job
994 | - files: List of input files
995 | - error_report_location: S3 location for error reports
996 | - job_configuration: Job configuration details
997 | - job_creation_date: When the job was created
998 | - job_last_update_date: When the job was last updated
999 | - adaptive_ingestion: Whether adaptive ingestion is enabled
1000 | - delete_files_after_import: Whether files are deleted after import
1001 | - Additional fields based on job status and execution
1002 |
1003 | Example:
1004 | # Get details for a specific job
1005 | result = describe_bulk_import_job(
1006 | job_id="12345678-1234-1234-1234-123456789012"
1007 | )
1008 |
1009 | if result['success']:
1010 | print(f"Job Status: {result['job_status']}")
1011 | print(f"Job Name: {result['job_name']}")
1012 | """
1013 | try:
1014 | # Validate parameters
1015 | if not isinstance(region, FieldInfo):
1016 | validate_region(region)
1017 |
1018 | # Validate job_id format (should be UUID)
1019 | if not job_id or not isinstance(job_id, str):
1020 | raise ValidationError('Job ID must be a non-empty string')
1021 |
1022 | # Basic UUID format validation (36 characters with hyphens)
1023 | if len(job_id) != 36 or job_id.count('-') != 4:
1024 | raise ValidationError(
1025 | 'Job ID must be in UUID format (e.g., 12345678-1234-1234-1234-123456789012)'
1026 | )
1027 |
1028 | client = create_sitewise_client(region)
1029 |
1030 | params: Dict[str, Any] = {
1031 | 'jobId': job_id,
1032 | }
1033 |
1034 | response = client.describe_bulk_import_job(**params)
1035 |
1036 | return {
1037 | 'success': True,
1038 | 'job_id': response.get('jobId'),
1039 | 'job_name': response.get('jobName'),
1040 | 'job_status': response.get('jobStatus'),
1041 | 'job_role_arn': response.get('jobRoleArn'),
1042 | 'files': response.get('files', []),
1043 | 'error_report_location': response.get('errorReportLocation', {}),
1044 | 'job_configuration': response.get('jobConfiguration', {}),
1045 | 'job_creation_date': response.get('jobCreationDate'),
1046 | 'job_last_update_date': response.get('jobLastUpdateDate'),
1047 | 'adaptive_ingestion': response.get('adaptiveIngestion'),
1048 | 'delete_files_after_import': response.get('deleteFilesAfterImport'),
1049 | }
1050 |
1051 | except ValidationError as e:
1052 | return {
1053 | 'success': False,
1054 | 'error': f'Validation error: {str(e)}',
1055 | 'error_code': 'ValidationException',
1056 | }
1057 | except ClientError as e:
1058 | return {
1059 | 'success': False,
1060 | 'error': str(e),
1061 | 'error_code': e.response['Error']['Code'],
1062 | }
1063 |
1064 |
1065 | @tool_metadata(readonly=True)
1066 | def execute_query(
1067 | query_statement: str = Field(
1068 | ..., description='SQL query statement to execute against AWS IoT SiteWise data'
1069 | ),
1070 | region: str = Field('us-east-1', description='AWS region'),
1071 | next_token: Optional[str] = Field(
1072 | None, description='The token to be used for the next set of paginated results'
1073 | ),
1074 | max_results: int = Field(100, description='The maximum number of results to return (1-10000)'),
1075 | ) -> Dict[str, Any]:
1076 | """Execute comprehensive SQL queries against AWS IoT SiteWise data using the executeQuery API.
1077 |
1078 | The AWS IoT SiteWise query language supports SQL capabilities including:
1079 | - Views: asset, asset_property, raw_time_series, \
1080 | latest_value_time_series, precomputed_aggregates
1081 | - SQL clauses: SELECT, FROM, WHERE, GROUP BY, ORDER BY, HAVING, LIMIT
1082 | - Functions: Aggregation, date/time, string, mathematical, conditional
1083 | - Operators: Comparison, logical, arithmetic, pattern matching (LIKE)
1084 | - JOIN operations: JOIN, LEFT JOIN,
1085 | UNION (prefer implicit joins for performance)
1086 |
1087 | Available Views and Schema (From Official AWS Documentation):
1088 |
1089 | ASSET VIEW: Contains information about the asset and model derivation
1090 | - asset_id (string), asset_name (string), asset_description (string)
1091 | - asset_model_id (string), parent_asset_id (string),
1092 | asset_external_id (string)
1093 | - asset_external_model_id (string), hierarchy_id (string)
1094 |
1095 | ASSET_PROPERTY VIEW: Contains information about the asset property's structure
1096 | - asset_id (string), property_id (string), property_name (string),
1097 | property_alias (string)
1098 | - property_external_id (string), asset_composite_model_id (string),
1099 | property_type (string)
1100 | - property_data_type (string), int_attribute_value (integer),
1101 | double_attribute_value (double)
1102 | - boolean_attribute_value (boolean), string_attribute_value (string)
1103 |
1104 | RAW_TIME_SERIES VIEW: Contains the historical data of the time series
1105 | - asset_id (string), property_id (string), property_alias (string),
1106 | event_timestamp (timestamp)
1107 | - quality (string), boolean_value (boolean), int_value (integer),
1108 | double_value (double), string_value (string)
1109 |
1110 | LATEST_VALUE_TIME_SERIES VIEW: Contains the latest value of the time series
1111 | - asset_id (string), property_id (string), property_alias (string),
1112 | event_timestamp (timestamp)
1113 | - quality (string), boolean_value (boolean), int_value (integer),
1114 | double_value (double), string_value (string)
1115 |
1116 | PRECOMPUTED_AGGREGATES VIEW: Contains automatically computed \
1117 | aggregated asset property values
1118 | - asset_id (string), property_id (string), property_alias (string),
1119 | event_timestamp (timestamp)
1120 | - quality (string), resolution (string), sum_value (double),
1121 | count_value (integer)
1122 | - average_value (double), maximum_value (double),
1123 | minimum_value (double), stdev_value (double)
1124 |
1125 | Complete SQL Function Reference (From AWS IoT SiteWise User Guide):
1126 |
1127 | DATE/TIME FUNCTIONS:
1128 | - DATE_ADD(
1129 | unit,
1130 | value,
1131 | date): Add time to date (e.g.,
1132 | DATE_ADD(DAY, 7, event_timestamp)) - DATE_SUB(
1133 | unit,
1134 | value,
1135 | date): Subtract time from date (e.g.,
1136 | DATE_SUB(
1137 | YEAR,
1138 | 2,
1139 | event_timestamp)) - TIMESTAMP_ADD(
1140 | unit,
1141 | value,
1142 | timestamp): Add time to timestamp
1143 | - TIMESTAMP_SUB(unit, value, timestamp): Subtract time from timestamp
1144 | - NOW(
1145 | ): Current timestamp (supported,
1146 | but use TIMESTAMP_ADD/SUB for math operations) - \
1147 | TIMESTAMP literals: Use TIMESTAMP '2023-01-01 00:00:00' for specific dates
1148 | - CAST(expression AS TIMESTAMP): Convert string to timestamp
1149 |
1150 | Note: NOW() IS supported. When doing math on NOW() or \
1151 | any timestamp, use TIMESTAMP_ADD/TIMESTAMP_SUB functions rather than \
1152 | +/- operators.
1153 |
1154 | TYPE CONVERSION FUNCTIONS:
1155 | - TO_DATE(integer): Convert epoch milliseconds to date
1156 | - TO_DATE(expression, format): Convert string to date with format
1157 | - TO_TIMESTAMP(double): Convert epoch seconds to timestamp
1158 | - TO_TIMESTAMP(string, format): Convert string to timestamp with format
1159 | - TO_TIME(int): Convert epoch milliseconds to time
1160 | - TO_TIME(string, format): Convert string to time with format
1161 | - CAST(expression AS data_type): Convert between BOOLEAN, INTEGER,
1162 | TIMESTAMP, DATE, STRING, etc.
1163 |
1164 | AGGREGATE FUNCTIONS:
1165 | - AVG(expression): Average value
1166 | - COUNT(expression): Count rows (COUNT(*) is supported)
1167 | - MAX(expression): Maximum value
1168 | - MIN(expression): Minimum value
1169 | - SUM(expression): Sum values
1170 | - STDDEV(expression): Standard deviation
1171 | - GROUP BY expression: Group results
1172 | - HAVING boolean-expression: Filter grouped results
1173 |
1174 | IMPORTANT LIMITATIONS:
1175 | - Window functions, CTEs (WITH clauses), DISTINCT, SELECT *, and \
1176 | ILIKE are NOT supported
1177 |
1178 | SUPPORTED FEATURES:
1179 | - CASE statements (CASE WHEN...THEN...ELSE...END pattern) ARE supported
1180 | - COUNT(*) IS supported (only SELECT * is blocked)
1181 | - Use implicit JOINs for better performance when possible
1182 |
1183 | Args:
1184 | query_statement: The SQL query statement to execute (max 64KB)
1185 | region: AWS region (default: us-east-1)
1186 | next_token: Token for paginated results
1187 | max_results: Maximum results to return (1-4000, default: 100)
1188 |
1189 | Returns:
1190 | Dictionary containing:
1191 | - success: Boolean indicating query success
1192 | - columns: List of column definitions
1193 | - rows: List of result rows
1194 | - next_token: Token for next page (if applicable)
1195 | - query_statistics: Execution statistics
1196 | - query_status: Query execution status
1197 |
1198 | Example Queries (Using Correct View and Column Names):
1199 |
1200 | Basic Asset Discovery:
1201 | "SELECT asset_id, asset_name, asset_model_id FROM asset"
1202 |
1203 | Metadata Filtering:
1204 | "SELECT a.asset_name, p.property_name FROM asset a, asset_property p \
1205 | WHERE a.asset_id = p.asset_id AND a.asset_name LIKE 'Windmill%'"
1206 |
1207 | Value Filtering with Time Range:
1208 | "SELECT a.asset_name, r.int_value FROM asset a, raw_time_series r
1209 | WHERE a.asset_id = r.asset_id
1210 | AND r.int_value > 30
1211 | AND r.event_timestamp > TIMESTAMP '2022-01-05 12:15:00'
1212 | AND r.event_timestamp < TIMESTAMP '2022-01-05 12:20:00'"
1213 |
1214 | Aggregation with Grouping:
1215 | "SELECT MAX(d.int_value) AS max_int_value, d.asset_id
1216 | FROM raw_time_series AS d
1217 | GROUP BY d.asset_id
1218 | HAVING MAX(d.int_value) > 5"
1219 |
1220 | Date/Time Manipulation:
1221 | "SELECT r.asset_id, r.int_value,
1222 | DATE_ADD(DAY, 7, r.event_timestamp) AS date_in_future,
1223 | DATE_SUB(YEAR, 2, r.event_timestamp) AS date_in_past,
1224 | TIMESTAMP_ADD(DAY, 2, r.event_timestamp) AS timestamp_in_future,
1225 | TIMESTAMP_SUB(DAY, 2, r.event_timestamp) AS timestamp_in_past
1226 | FROM raw_time_series AS r"
1227 |
1228 | Type Conversion Examples:
1229 | "SELECT r.asset_id, TO_DATE(r.event_timestamp) AS date_value,
1230 | TO_TIME(r.event_timestamp) AS time_value
1231 | FROM raw_time_series AS r"
1232 |
1233 | Attribute Property Filtering (For Attribute Properties Only - \
1234 | Note: Only one attribute value type can be non-null per property):
1235 | "SELECT p.property_name,
1236 | CASE
1237 | WHEN p.string_attribute_value IS NOT NULL THEN p.string_attribute_value
1238 | WHEN p.double_attribute_value IS NOT NULL THEN \
1239 | CAST(p.double_attribute_value AS STRING)
1240 | ELSE 'NULL'
1241 | END as attribute_value
1242 | FROM asset_property p
1243 | WHERE p.property_type = 'attribute'
1244 | AND (p.string_attribute_value LIKE 'my-property-%' OR \
1245 | p.double_attribute_value > 100.0)"
1246 |
1247 | Precomputed Aggregates (Include quality and resolution filters):
1248 | "SELECT asset_id, property_id, average_value, event_timestamp
1249 | FROM precomputed_aggregates
1250 | WHERE quality = 'GOOD'
1251 | AND resolution = '1h'
1252 | AND event_timestamp BETWEEN TIMESTAMP '2023-01-01 00:00:00' AND \
1253 | TIMESTAMP '2023-01-02 00:00:00'"
1254 |
1255 | Implicit JOIN for Better Performance:
1256 | "SELECT a.asset_name, p.property_name, r.double_value
1257 | FROM asset a, asset_property p, raw_time_series r
1258 | WHERE a.asset_id = p.asset_id
1259 | AND p.property_id = r.property_id
1260 | AND r.quality = 'GOOD'"
1261 |
1262 | Data Quality Analysis:
1263 | "SELECT asset_id, property_alias,
1264 | SUM(CASE WHEN quality = 'GOOD' THEN 1 ELSE 0 END) as good_readings,
1265 | SUM(CASE WHEN quality = 'BAD' THEN 1 ELSE 0 END) as bad_readings,
1266 | ROUND(
1267 | SUM(CASE WHEN quality = 'GOOD' THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
1268 |
1269 | 2) as quality_percent FROM raw_time_series WHERE \
1270 | event_timestamp >= TIMESTAMP '2023-01-01 00:00:00'
1271 | GROUP BY asset_id, property_alias HAVING COUNT(*) > 10"
1272 |
1273 | CASE Statement and COUNT(*) Examples:
1274 | "SELECT asset_id, COUNT(*) as total_records,
1275 | CASE WHEN COUNT(*) = 0 THEN 'No Data' ELSE 'Has Data' END as data_status
1276 | FROM raw_time_series GROUP BY asset_id"
1277 |
1278 | Query Optimization Guidelines (From AWS Documentation):
1279 |
1280 | 1. METADATA FILTERS - \
1281 | Use WHERE clause with these operators for metadata fields:
1282 | - Equals (=), Not equals (!=), LIKE, IN, AND, OR
1283 | - Use literals on right side of operators for better performance
1284 |
1285 | 2. RAW DATA FILTERS - Always filter on event_timestamp using:
1286 | - Equals (
1287 | =), Greater than (>), Less than (<), Greater/Less than or \
1288 | equals (>=,
1289 | <=) - BETWEEN, AND operators
1290 | - Avoid != and OR operators as they don't limit data scan effectively
1291 |
1292 | 3. PRECOMPUTED AGGREGATES - Always specify:
1293 | - Quality filter (quality = 'GOOD') to reduce data scanned
1294 | - Resolution filter (1m, 15m, 1h, 1d) to avoid full table scan
1295 |
1296 | 4. JOIN OPTIMIZATION:
1297 | - Use implicit JOINs instead of explicit JOIN keyword when possible
1298 | - Push metadata filters into subqueries for better performance
1299 | - Apply filters on individual JOINed tables to minimize data scanned
1300 |
1301 | 5. PERFORMANCE TIPS:
1302 | - Use LIMIT clause to reduce data scanned for some queries
1303 | - Set page size to maximum 20000 for large queries
1304 | - Use attribute value columns (
1305 | double_attribute_value,
1306 | etc.) for better performance than latest_value_time_series - \
1307 | Filter on asset_id, property_id for indexed access
1308 | - Always include quality = 'GOOD' filters for reliable data
1309 |
1310 | """
1311 | try:
1312 | # Validate parameters
1313 | if not query_statement or not query_statement.strip():
1314 | raise ValidationError('Query statement cannot be empty')
1315 |
1316 | if len(query_statement) > 65536: # 64KB limit
1317 | raise ValidationError('Query statement cannot exceed 64KB')
1318 |
1319 | validate_region(region)
1320 | validate_max_results(max_results, min_val=1, max_val=4000)
1321 |
1322 | if next_token and len(next_token) > 4096:
1323 | raise ValidationError('Next token too long')
1324 |
1325 | client = create_sitewise_client(region)
1326 |
1327 | params: Dict[str, Any] = {
1328 | 'queryStatement': query_statement.strip(),
1329 | 'maxResults': max_results,
1330 | }
1331 |
1332 | if next_token:
1333 | params['nextToken'] = next_token
1334 |
1335 | response = client.execute_query(**params)
1336 |
1337 | return {
1338 | 'success': True,
1339 | 'columns': response.get('columns', []),
1340 | 'rows': response.get('rows', []),
1341 | 'next_token': response.get('nextToken', ''),
1342 | 'query_statistics': response.get('queryStatistics', {}),
1343 | 'query_status': response.get('queryStatus', 'COMPLETED'),
1344 | }
1345 |
1346 | except ValidationError as e:
1347 | return {
1348 | 'success': False,
1349 | 'error': f'Validation error: {str(e)}',
1350 | 'error_code': 'ValidationException',
1351 | }
1352 | except ClientError as e:
1353 | return {
1354 | 'success': False,
1355 | 'error': str(e),
1356 | 'error_code': e.response['Error']['Code'],
1357 | }
1358 |
1359 |
1360 | @tool_metadata(readonly=False)
1361 | def create_bulk_import_iam_role(
1362 | role_name: str = Field(
1363 | 'IoTSiteWiseBulkImportAssumableRole',
1364 | description='Name of bulk import permissions IAM role',
1365 | ),
1366 | data_bucket_names: List[str] = Field(..., description='S3 bucket names containing data files'),
1367 | error_bucket_name: str = Field(..., description='S3 bucket name for error reports'),
1368 | region: str = Field('us-east-1', description='AWS region'),
1369 | ) -> Dict[str, Any]:
1370 | """Create an IAM role for AWS IoT SiteWise bulk import jobs."""
1371 | try:
1372 | # Create IAM client
1373 | iam_client = create_iam_client(region)
1374 |
1375 | # Trust policy allowing IoT SiteWise to assume the role
1376 | trust_policy = {
1377 | 'Version': '2012-10-17',
1378 | 'Statement': [
1379 | {
1380 | 'Effect': 'Allow',
1381 | 'Principal': {'Service': 'iotsitewise.amazonaws.com'},
1382 | 'Action': 'sts:AssumeRole',
1383 | }
1384 | ],
1385 | }
1386 |
1387 | # Create the IAM role
1388 | create_role_response = iam_client.create_role(
1389 | RoleName=role_name,
1390 | AssumeRolePolicyDocument=json.dumps(trust_policy),
1391 | Description='IAM role for IoT SiteWise bulk import jobs',
1392 | )
1393 |
1394 | # Create policy for S3 permissions following AWS documentation
1395 | data_bucket_resources = []
1396 | for bucket in data_bucket_names:
1397 | data_bucket_resources.extend([f'arn:aws:s3:::{bucket}', f'arn:aws:s3:::{bucket}/*'])
1398 |
1399 | policy_document = {
1400 | 'Version': '2012-10-17',
1401 | 'Statement': [
1402 | {
1403 | 'Effect': 'Allow',
1404 | 'Action': ['s3:GetObject', 's3:GetBucketLocation'],
1405 | 'Resource': data_bucket_resources,
1406 | },
1407 | {
1408 | 'Effect': 'Allow',
1409 | 'Action': ['s3:PutObject', 's3:GetObject', 's3:GetBucketLocation'],
1410 | 'Resource': [
1411 | f'arn:aws:s3:::{error_bucket_name}',
1412 | f'arn:aws:s3:::{error_bucket_name}/*',
1413 | ],
1414 | },
1415 | ],
1416 | }
1417 |
1418 | # Attach inline policy to the role
1419 | iam_client.put_role_policy(
1420 | RoleName=role_name,
1421 | PolicyName=f'{role_name}Policy',
1422 | PolicyDocument=json.dumps(policy_document),
1423 | )
1424 |
1425 | return {
1426 | 'success': True,
1427 | 'role_arn': create_role_response['Role']['Arn'],
1428 | 'role_name': role_name,
1429 | }
1430 |
1431 | except (ValidationError, ClientError) as e:
1432 | return {
1433 | 'success': False,
1434 | 'error': str(e),
1435 | }
1436 |
1437 |
1438 | create_bulk_import_job_tool = Tool.from_function(
1439 | fn=create_bulk_import_job,
1440 | name='create_bulk_import_job',
1441 | description=(
1442 | 'Create a bulk import job to ingest data from Amazon S3 to AWS IoT SiteWise. '
1443 | 'Supports both historical data ingestion (adaptive_ingestion=False) and buffered '
1444 | 'ingestion (adaptive_ingestion=True) for real-time processing of recent data. '
1445 | 'Supports CSV and Parquet file formats with comprehensive validation and error handling.'
1446 | ),
1447 | )
1448 |
1449 | create_buffered_ingestion_job_tool = Tool.from_function(
1450 | fn=create_buffered_ingestion_job,
1451 | name='create_buffered_ingestion_job',
1452 | description=(
1453 | 'Create a buffered ingestion job to ingest data from Amazon S3 to AWS IoT SiteWise '
1454 | 'with adaptive ingestion enabled for real-time processing of recent data (within 30 days). '
1455 | 'This is a convenience function that automatically sets adaptive_ingestion=True. '
1456 | 'Supports CSV and Parquet file formats with comprehensive validation and error handling.'
1457 | ),
1458 | )
1459 |
1460 | batch_put_asset_property_value_tool = Tool.from_function(
1461 | fn=batch_put_asset_property_value,
1462 | name='batch_put_asset_property_value',
1463 | description=('Send a list of asset property values to AWS IoT SiteWise for data ingestion.'),
1464 | )
1465 |
1466 | get_asset_property_value_tool = Tool.from_function(
1467 | fn=get_asset_property_value,
1468 | name='get_asset_property_value',
1469 | description=('Get the current value for a given asset property in AWS IoT SiteWise.'),
1470 | )
1471 |
1472 | get_asset_property_value_history_tool = Tool.from_function(
1473 | fn=get_asset_property_value_history,
1474 | name='get_asset_property_value_history',
1475 | description=('Get the historical values for an asset property in AWS IoT SiteWise.'),
1476 | )
1477 |
1478 | get_asset_property_aggregates_tool = Tool.from_function(
1479 | fn=get_asset_property_aggregates,
1480 | name='get_asset_property_aggregates',
1481 | description='Get aggregated values (average, count, maximum, minimum, '
1482 | 'sum, standard deviation) for an asset property in AWS IoT SiteWise.',
1483 | )
1484 |
1485 | get_interpolated_asset_property_values_tool = Tool.from_function(
1486 | fn=get_interpolated_asset_property_values,
1487 | name='get_interpl_asset_property_values',
1488 | description=(
1489 | 'Get interpolated values for an asset property for a '
1490 | 'specified time interval in AWS IoT SiteWise.'
1491 | ),
1492 | )
1493 |
1494 | batch_get_asset_property_value_tool = Tool.from_function(
1495 | fn=batch_get_asset_property_value,
1496 | name='batch_get_asset_property_value',
1497 | description=('Get the current values for multiple asset properties in AWS IoT SiteWise.'),
1498 | )
1499 |
1500 | batch_get_asset_property_value_history_tool = Tool.from_function(
1501 | fn=batch_get_asset_property_value_history,
1502 | name='batch_get_asset_property_value_hist',
1503 | description=('Get the historical values for multiple asset properties in AWS IoT SiteWise.'),
1504 | )
1505 |
1506 | batch_get_asset_property_aggregates_tool = Tool.from_function(
1507 | fn=batch_get_asset_property_aggregates,
1508 | name='batch_get_asset_property_aggregates',
1509 | description=('Get aggregated values for multiple asset properties in AWS IoT SiteWise.'),
1510 | )
1511 |
1512 | list_bulk_import_jobs_tool = Tool.from_function(
1513 | fn=list_bulk_import_jobs,
1514 | name='list_bulk_import_jobs',
1515 | description=(
1516 | 'List bulk import jobs in AWS IoT SiteWise with optional filtering by status '
1517 | '(ALL, PENDING, RUNNING, CANCELLED, FAILED, COMPLETED_WITH_FAILURES, COMPLETED). '
1518 | 'Returns paginated job summaries with basic information like job ID, name, status, and timestamps.'
1519 | ),
1520 | )
1521 |
1522 | describe_bulk_import_job_tool = Tool.from_function(
1523 | fn=describe_bulk_import_job,
1524 | name='describe_bulk_import_job',
1525 | description=(
1526 | 'Get detailed information about a specific bulk import job in AWS IoT SiteWise '
1527 | 'including configuration, status, progress, error information, and execution statistics. '
1528 | 'Requires the job ID in UUID format.'
1529 | ),
1530 | )
1531 |
1532 | create_bulk_import_iam_role_tool = Tool.from_function(
1533 | fn=create_bulk_import_iam_role,
1534 | name='create_bulk_import_iam_role',
1535 | description=(
1536 | 'Create an IAM role for AWS IoT SiteWise bulk import jobs with the necessary '
1537 | 'S3 permissions and trust policy. Automatically configures read access to data '
1538 | 'buckets and write access to error bucket for IoT SiteWise service.'
1539 | ),
1540 | )
1541 |
1542 | execute_query_tool = Tool.from_function(
1543 | fn=execute_query,
1544 | name='execute_query',
1545 | description=(
1546 | 'Execute comprehensive SQL queries against AWS IoT SiteWise data '
1547 | 'with SQL capabilities including views (asset, asset_property, '
1548 | 'raw_time_series, latest_value_time_series, precomputed_aggregates), '
1549 | 'functions (aggregation, date/time, string, mathematical), '
1550 | 'operators, joins, and analytics for industrial IoT data exploration.'
1551 | ),
1552 | )
1553 |
```