This is page 556 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
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ └── http_header_validation_middleware.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
│ │ │ ├── middleware
│ │ │ │ └── test_http_header_validation_middleware.py
│ │ │ ├── parser
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_file_path_detection.py
│ │ │ │ ├── test_lexer.py
│ │ │ │ ├── test_parser_customizations.py
│ │ │ │ └── test_parser.py
│ │ │ ├── test_security_policy.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-appsync-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_appsync_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── decorators.py
│ │ │ ├── helpers.py
│ │ │ ├── operations
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ └── validators.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_all_create_tools_write_protection.py
│ │ │ ├── test_create_api_cache.py
│ │ │ ├── test_create_api_key.py
│ │ │ ├── test_create_api.py
│ │ │ ├── test_create_channel_namespace.py
│ │ │ ├── test_create_datasource_tool.py
│ │ │ ├── test_create_datasource.py
│ │ │ ├── test_create_domain_name.py
│ │ │ ├── test_create_function.py
│ │ │ ├── test_create_graphql_api.py
│ │ │ ├── test_create_resolver.py
│ │ │ ├── test_create_schema_tool.py
│ │ │ ├── test_create_schema.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validators.py
│ │ │ └── test_write_operation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-custom-model-import-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_custom_model_import_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── prompts.py
│ │ │ ├── server.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── imported_model_service.py
│ │ │ │ └── model_import_service.py
│ │ │ ├── tools
│ │ │ │ ├── create_model_import_job.py
│ │ │ │ ├── delete_imported_model.py
│ │ │ │ ├── get_imported_model.py
│ │ │ │ ├── get_model_import_job.py
│ │ │ │ ├── list_imported_models.py
│ │ │ │ └── list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ └── matching.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── services
│ │ │ │ ├── test_imported_model_service.py
│ │ │ │ └── test_model_import_service.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_llm_context.py
│ │ │ ├── test_prompts.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── test_create_model_import_job.py
│ │ │ │ ├── test_delete_imported_model.py
│ │ │ │ ├── test_get_imported_model.py
│ │ │ │ ├── test_get_model_import_job.py
│ │ │ │ ├── test_list_imported_models.py
│ │ │ │ └── test_list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── test_aws.py
│ │ │ ├── test_config.py
│ │ │ └── test_matching.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-data-automation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_data_automation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── helpers.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-dataprocessing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_dataprocessing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── data_catalog_database_manager.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ └── data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── athena_data_catalog_handler.py
│ │ │ │ │ ├── athena_query_handler.py
│ │ │ │ │ └── athena_workgroup_handler.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── emr_ec2_cluster_handler.py
│ │ │ │ │ ├── emr_ec2_instance_handler.py
│ │ │ │ │ └── emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── crawler_handler.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ ├── glue_commons_handler.py
│ │ │ │ ├── glue_etl_handler.py
│ │ │ │ ├── interactive_sessions_handler.py
│ │ │ │ └── worklows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena_models.py
│ │ │ │ ├── common_resource_models.py
│ │ │ │ ├── data_catalog_models.py
│ │ │ │ ├── emr_models.py
│ │ │ │ └── glue_models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── consts.py
│ │ │ ├── logging_helper.py
│ │ │ └── sql_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_data_catalog_database_manager.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ └── test_data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_athena_data_catalog_handler.py
│ │ │ │ │ ├── test_athena_query_handler.py
│ │ │ │ │ ├── test_athena_workgroup_handler.py
│ │ │ │ │ └── test_custom_tags_athena.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── test_common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_custom_tags_emr.py
│ │ │ │ │ ├── test_emr_ec2_cluster_handler.py
│ │ │ │ │ ├── test_emr_ec2_instance_handler.py
│ │ │ │ │ └── test_emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_crawler_handler.py
│ │ │ │ ├── test_custom_tags_glue.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ ├── test_glue_commons_handler.py
│ │ │ │ ├── test_glue_etl_handler.py
│ │ │ │ ├── test_glue_interactive_sessions_handler.py
│ │ │ │ └── test_glue_workflows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_athena_models.py
│ │ │ │ ├── test_common_resource_models.py
│ │ │ │ ├── test_data_catalog_models.py
│ │ │ │ ├── test_emr_models.py
│ │ │ │ ├── test_glue_models.py
│ │ │ │ ├── test_interactive_sessions_models.py
│ │ │ │ └── test_workflows_models.py
│ │ │ ├── test_init.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_custom_tags.py
│ │ │ ├── test_logging_helper.py
│ │ │ └── test_sql_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-diagram-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_diagram_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── diagrams_tools.py
│ │ │ ├── models.py
│ │ │ ├── scanner.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ └── example_diagrams
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_example.py
│ │ │ │ ├── flow_example.py
│ │ │ │ └── sequence_example.py
│ │ │ ├── test_diagrams.py
│ │ │ ├── test_models.py
│ │ │ ├── test_sarif_fix.py
│ │ │ ├── test_scanner.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-documentation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_documentation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── server_aws_cn.py
│ │ │ ├── server_aws.py
│ │ │ ├── server_utils.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── basic-usage.gif
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── constants.py
│ │ │ ├── resources
│ │ │ │ └── lambda_sns_raw.html
│ │ │ ├── test_aws_cn_get_available_services_live.py
│ │ │ ├── test_aws_cn_read_documentation_live.py
│ │ │ ├── test_aws_read_documentation_live.py
│ │ │ ├── test_aws_recommend_live.py
│ │ │ ├── test_aws_search_live.py
│ │ │ ├── test_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/timestream-for-influxdb-mcp-server/tests/test_server.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 | """Tests for the Timestream for InfluxDB MCP Server."""
16 |
17 | import botocore.exceptions
18 | import pytest
19 | from awslabs.timestream_for_influxdb_mcp_server.server import (
20 | create_db_cluster,
21 | create_db_instance,
22 | create_db_parameter_group,
23 | delete_db_cluster,
24 | delete_db_instance,
25 | get_db_cluster,
26 | get_db_instance,
27 | get_db_parameter_group,
28 | get_influxdb_client,
29 | get_timestream_influxdb_client,
30 | influxdb_query,
31 | influxdb_write_line_protocol,
32 | influxdb_write_points,
33 | list_db_clusters,
34 | list_db_clusters_by_status,
35 | list_db_instances,
36 | list_db_instances_by_status,
37 | list_db_instances_for_cluster,
38 | list_db_parameter_groups,
39 | list_tags_for_resource,
40 | tag_resource,
41 | untag_resource,
42 | update_db_cluster,
43 | update_db_instance,
44 | )
45 | from unittest.mock import MagicMock, patch
46 |
47 |
48 | class TestClientCreation:
49 | """Tests for client creation functions."""
50 |
51 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.boto3')
52 | def test_get_timestream_influxdb_client_happy_path(self, mock_boto3):
53 | """Test get_timestream_influxdb_client with default parameters."""
54 | # Arrange
55 | mock_session = MagicMock()
56 | mock_boto3.Session.return_value = mock_session
57 | mock_client = MagicMock()
58 | mock_session.client.return_value = mock_client
59 |
60 | # Act
61 | client = get_timestream_influxdb_client()
62 |
63 | # Assert
64 | mock_boto3.Session.assert_called_once_with(region_name='us-east-1')
65 | mock_session.client.assert_called_once_with('timestream-influxdb')
66 | assert client == mock_client
67 |
68 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.boto3')
69 | def test_get_timestream_influxdb_client_exception_path(self, mock_boto3):
70 | """Test get_timestream_influxdb_client when an exception occurs."""
71 | # Arrange
72 | mock_boto3.Session.side_effect = Exception('Connection error')
73 |
74 | # Act & Assert
75 | with pytest.raises(Exception) as excinfo:
76 | get_timestream_influxdb_client()
77 |
78 | assert 'Connection error' in str(excinfo.value)
79 |
80 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.InfluxDBClient')
81 | def test_get_influxdb_client_happy_path(self, mock_influxdb_client):
82 | """Test get_influxdb_client function with valid parameters."""
83 | # Arrange
84 | url = 'https://influxdb-example.aws:8086'
85 | token = 'test-token'
86 | org = 'test-org'
87 | timeout = 5000
88 | verify_ssl = False
89 | mock_client = MagicMock()
90 | mock_influxdb_client.return_value = mock_client
91 |
92 | # Act
93 | client = get_influxdb_client(url, token, org, timeout, verify_ssl)
94 |
95 | # Assert
96 | mock_influxdb_client.assert_called_once_with(
97 | url=url, token=token, org=org, timeout=timeout, verify_ssl=verify_ssl
98 | )
99 | assert client == mock_client
100 |
101 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.InfluxDBClient')
102 | def test_get_influxdb_client_exception_path(self, mock_influxdb_client):
103 | """Test get_influxdb_client function with invalid url."""
104 | # Arrange
105 | url = 'random-schema://influxdb-example.aws:8086'
106 | token = 'test-token'
107 | org = 'test-org'
108 | timeout = 5000
109 | verify_ssl = False
110 |
111 | # Act and assert
112 | with pytest.raises(Exception) as excinfo:
113 | get_influxdb_client(url, token, org, timeout, verify_ssl)
114 |
115 | assert 'URL must use HTTP(S) protocol' in str(excinfo.value)
116 |
117 |
118 | class TestDbClusterOperations:
119 | """Tests for DB cluster operations."""
120 |
121 | @pytest.mark.asyncio
122 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
123 | async def test_create_db_cluster_happy_path(self, mock_get_client):
124 | """Test create_db_cluster function with valid parameters."""
125 | # Arrange
126 | mock_client = MagicMock()
127 | mock_get_client.return_value = mock_client
128 | mock_client.create_db_cluster.return_value = {'dbClusterId': 'test-cluster-id'}
129 |
130 | # Test parameters
131 | name = 'test-cluster'
132 | db_instance_type = 'db.influx.large'
133 | password = ''
134 | allocated_storage_gb = 100
135 | vpc_security_group_ids = ['sg-12345']
136 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
137 | tags = {'Environment': 'Test'}
138 |
139 | # Act
140 | result = await create_db_cluster(
141 | name=name,
142 | db_instance_type=db_instance_type,
143 | password=password,
144 | allocated_storage_gb=allocated_storage_gb,
145 | vpc_security_group_ids=vpc_security_group_ids,
146 | vpc_subnet_ids=vpc_subnet_ids,
147 | tags=tags,
148 | tool_write_mode=True,
149 | )
150 |
151 | # Assert
152 | mock_get_client.assert_called_once()
153 | mock_client.create_db_cluster.assert_called_once()
154 | call_args = mock_client.create_db_cluster.call_args[1]
155 | assert call_args['name'] == name
156 | assert call_args['dbInstanceType'] == db_instance_type
157 | assert call_args['password'] == password
158 | assert call_args['allocatedStorage'] == allocated_storage_gb
159 | assert call_args['vpcSecurityGroupIds'] == vpc_security_group_ids
160 | assert call_args['vpcSubnetIds'] == vpc_subnet_ids
161 |
162 | # Check if publiclyAccessible is a Field object and extract its default value if needed
163 | if hasattr(call_args['publiclyAccessible'], 'default'):
164 | assert call_args['publiclyAccessible'].default is True
165 | else:
166 | assert call_args['publiclyAccessible'] is True
167 |
168 | # Check if tags is a list of dictionaries with Key and Value
169 | if tags:
170 | if hasattr(call_args['tags'], 'items'):
171 | # If tags is a dictionary-like object
172 | tag_list = []
173 | for k, v in call_args['tags'].items():
174 | tag_list.append({'Key': k, 'Value': v})
175 | assert tag_list == [{'Key': 'Environment', 'Value': 'Test'}]
176 | else:
177 | # If tags is already a list
178 | assert call_args['tags'] == "[{'Key': 'Environment', 'Value': 'Test'}]"
179 |
180 | assert result == {'dbClusterId': 'test-cluster-id'}
181 |
182 | @pytest.mark.asyncio
183 | async def test_create_db_cluster_read_only_mode(self):
184 | """Test tool in read-only mode."""
185 | # Test parameters
186 | name = 'test-cluster'
187 | db_instance_type = 'db.influx.large'
188 | password = ''
189 | allocated_storage_gb = 100
190 | vpc_security_group_ids = ['sg-12345']
191 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
192 |
193 | with pytest.raises(Exception) as excinfo:
194 | await create_db_cluster(
195 | name=name,
196 | db_instance_type=db_instance_type,
197 | password=password,
198 | allocated_storage_gb=allocated_storage_gb,
199 | vpc_security_group_ids=vpc_security_group_ids,
200 | vpc_subnet_ids=vpc_subnet_ids,
201 | tool_write_mode=False,
202 | )
203 | assert (
204 | 'CreateDbCluster tool invocation not allowed when tool-write-mode is set to False'
205 | in str(excinfo.value)
206 | )
207 |
208 | @pytest.mark.asyncio
209 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
210 | async def test_create_db_cluster_exception_path(self, mock_get_client):
211 | """Test create_db_cluster function when an exception occurs."""
212 | # Arrange
213 | mock_client = MagicMock()
214 | mock_get_client.return_value = mock_client
215 | mock_client.create_db_cluster.side_effect = botocore.exceptions.ClientError(
216 | {'Error': {'Code': 'ValidationException', 'Message': 'Invalid parameter value'}},
217 | 'CreateDbCluster',
218 | )
219 |
220 | # Test parameters
221 | name = 'test-cluster'
222 | db_instance_type = 'db.influx.large'
223 | password = ''
224 | allocated_storage_gb = 100
225 | vpc_security_group_ids = ['sg-12345']
226 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
227 |
228 | # Act & Assert
229 | with pytest.raises(Exception) as excinfo:
230 | await create_db_cluster(
231 | name=name,
232 | db_instance_type=db_instance_type,
233 | password=password,
234 | allocated_storage_gb=allocated_storage_gb,
235 | vpc_security_group_ids=vpc_security_group_ids,
236 | vpc_subnet_ids=vpc_subnet_ids,
237 | tool_write_mode=True,
238 | )
239 |
240 | # Check if the exception is a ClientError with ValidationException code
241 | if isinstance(excinfo.value, botocore.exceptions.ClientError):
242 | assert excinfo.value.response['Error']['Code'] == 'ValidationException'
243 | else:
244 | # If it's a different exception, check if ValidationException is in the message
245 | assert 'ValidationException' in str(excinfo.value) or 'items' in str(excinfo.value)
246 |
247 | @pytest.mark.asyncio
248 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
249 | async def test_get_db_cluster_happy_path(self, mock_get_client):
250 | """Test get_db_cluster function with valid parameters."""
251 | # Arrange
252 | mock_client = MagicMock()
253 | mock_get_client.return_value = mock_client
254 | mock_client.get_db_cluster.return_value = {
255 | 'id': 'test-cluster-id',
256 | 'name': 'test-cluster',
257 | 'status': 'available',
258 | }
259 |
260 | # Act
261 | result = await get_db_cluster(db_cluster_id='test-cluster-id')
262 |
263 | # Assert
264 | mock_get_client.assert_called_once()
265 | mock_client.get_db_cluster.assert_called_once_with(dbClusterId='test-cluster-id')
266 | assert result == {'id': 'test-cluster-id', 'name': 'test-cluster', 'status': 'available'}
267 |
268 | @pytest.mark.asyncio
269 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
270 | async def test_get_db_cluster_exception_path(self, mock_get_client):
271 | """Test get_db_cluster function when an exception occurs."""
272 | # Arrange
273 | mock_client = MagicMock()
274 | mock_get_client.return_value = mock_client
275 | mock_client.get_db_cluster.side_effect = botocore.exceptions.ClientError(
276 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'DB cluster not found'}},
277 | 'GetDbCluster',
278 | )
279 |
280 | # Act & Assert
281 | with pytest.raises(Exception) as excinfo:
282 | await get_db_cluster(db_cluster_id='non-existent-cluster')
283 |
284 | assert 'ResourceNotFoundException' in str(excinfo.value)
285 | mock_get_client.assert_called_once()
286 | mock_client.get_db_cluster.assert_called_once()
287 |
288 | @pytest.mark.asyncio
289 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
290 | async def test_delete_db_cluster_happy_path(self, mock_get_client):
291 | """Test delete_db_cluster function with valid parameters."""
292 | # Arrange
293 | mock_client = MagicMock()
294 | mock_get_client.return_value = mock_client
295 | mock_client.delete_db_cluster.return_value = {
296 | 'dbClusterId': 'test-cluster-id',
297 | 'dbClusterStatus': 'deleting',
298 | }
299 |
300 | # Act
301 | result = await delete_db_cluster(db_cluster_id='test-cluster-id', tool_write_mode=True)
302 |
303 | # Assert
304 | mock_get_client.assert_called_once()
305 | mock_client.delete_db_cluster.assert_called_once_with(dbClusterId='test-cluster-id')
306 | assert result == {'dbClusterId': 'test-cluster-id', 'dbClusterStatus': 'deleting'}
307 |
308 | @pytest.mark.asyncio
309 | async def test_delete_db_cluster_read_only_mode(self):
310 | """Test tool in read-only mode."""
311 | # Act
312 | with pytest.raises(Exception) as excinfo:
313 | await delete_db_cluster(db_cluster_id='test-cluster-id', tool_write_mode=False)
314 |
315 | # Assert
316 | assert (
317 | 'DeleteDbCluster tool invocation not allowed when tool-write-mode is set to False'
318 | in str(excinfo.value)
319 | )
320 |
321 | @pytest.mark.asyncio
322 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
323 | async def test_delete_db_cluster_exception_path(self, mock_get_client):
324 | """Test delete_db_cluster function when an exception occurs."""
325 | # Arrange
326 | mock_client = MagicMock()
327 | mock_get_client.return_value = mock_client
328 | mock_client.delete_db_cluster.side_effect = botocore.exceptions.ClientError(
329 | {
330 | 'Error': {
331 | 'Code': 'InvalidDBClusterState',
332 | 'Message': 'DB cluster has instances attached',
333 | }
334 | },
335 | 'DeleteDbCluster',
336 | )
337 |
338 | # Act & Assert
339 | with pytest.raises(Exception) as excinfo:
340 | await delete_db_cluster(db_cluster_id='cluster-with-instances', tool_write_mode=True)
341 |
342 | assert 'InvalidDBClusterState' in str(excinfo.value)
343 | mock_get_client.assert_called_once()
344 | mock_client.delete_db_cluster.assert_called_once()
345 |
346 | @pytest.mark.asyncio
347 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
348 | async def test_list_db_clusters_happy_path(self, mock_get_client):
349 | """Test list_db_clusters function with valid parameters."""
350 | # Arrange
351 | mock_client = MagicMock()
352 | mock_get_client.return_value = mock_client
353 | mock_client.list_db_clusters.return_value = {
354 | 'items': [{'id': 'cluster-1'}, {'id': 'cluster-2'}],
355 | 'nextToken': 'next-token',
356 | }
357 |
358 | # Act
359 | result = await list_db_clusters(next_token='token', max_results=10)
360 |
361 | # Assert
362 | mock_get_client.assert_called_once()
363 | mock_client.list_db_clusters.assert_called_once_with(nextToken='token', maxResults='10')
364 | assert result == {
365 | 'items': [{'id': 'cluster-1'}, {'id': 'cluster-2'}],
366 | 'nextToken': 'next-token',
367 | }
368 |
369 | @pytest.mark.asyncio
370 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
371 | async def test_list_db_clusters_exception_path(self, mock_get_client):
372 | """Test list_db_clusters function when an exception occurs."""
373 | # Arrange
374 | mock_client = MagicMock()
375 | mock_get_client.return_value = mock_client
376 | mock_client.list_db_clusters.side_effect = botocore.exceptions.ClientError(
377 | {
378 | 'Error': {
379 | 'Code': 'ServiceUnavailable',
380 | 'Message': 'Service is currently unavailable',
381 | }
382 | },
383 | 'ListDbClusters',
384 | )
385 |
386 | # Act & Assert
387 | with pytest.raises(Exception) as excinfo:
388 | await list_db_clusters()
389 |
390 | assert 'ServiceUnavailable' in str(excinfo.value)
391 | mock_get_client.assert_called_once()
392 | mock_client.list_db_clusters.assert_called_once()
393 |
394 | @pytest.mark.asyncio
395 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
396 | async def test_update_db_cluster_happy_path(self, mock_get_client):
397 | """Test update_db_cluster function with valid parameters."""
398 | # Arrange
399 | mock_client = MagicMock()
400 | mock_get_client.return_value = mock_client
401 | mock_client.update_db_cluster.return_value = {
402 | 'dbClusterId': 'test-cluster-id',
403 | 'dbClusterStatus': 'modifying',
404 | 'dbInstanceType': 'db.influx.xlarge',
405 | }
406 |
407 | # Test parameters
408 | db_cluster_id = 'test-cluster-id'
409 | db_instance_type = 'db.influx.xlarge'
410 | port = 8087
411 | failover_mode = 'automatic'
412 |
413 | # Act
414 | result = await update_db_cluster(
415 | db_cluster_id=db_cluster_id,
416 | db_instance_type=db_instance_type,
417 | port=port,
418 | failover_mode=failover_mode,
419 | tool_write_mode=True,
420 | )
421 |
422 | # Assert
423 | mock_get_client.assert_called_once()
424 | mock_client.update_db_cluster.assert_called_once()
425 | call_args = mock_client.update_db_cluster.call_args[1]
426 | assert call_args['dbClusterId'] == db_cluster_id
427 | assert call_args['dbInstanceType'] == db_instance_type
428 | assert call_args['port'] == str(port)
429 | assert call_args['failoverMode'] == failover_mode
430 | assert result == {
431 | 'dbClusterId': 'test-cluster-id',
432 | 'dbClusterStatus': 'modifying',
433 | 'dbInstanceType': 'db.influx.xlarge',
434 | }
435 |
436 | @pytest.mark.asyncio
437 | async def test_update_db_cluster_read_only_mode(self):
438 | """Test tool in read-only mode."""
439 | db_cluster_id = 'cluster-in-use'
440 | db_instance_type = 'db.influx.xlarge'
441 |
442 | # Act
443 | with pytest.raises(Exception) as excinfo:
444 | await update_db_cluster(
445 | db_cluster_id=db_cluster_id,
446 | db_instance_type=db_instance_type,
447 | tool_write_mode=False,
448 | )
449 |
450 | # Assert
451 | assert (
452 | 'UpdateDbCluster tool invocation not allowed when tool-write-mode is set to False'
453 | in str(excinfo.value)
454 | )
455 |
456 | @pytest.mark.asyncio
457 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
458 | async def test_update_db_cluster_exception_path(self, mock_get_client):
459 | """Test update_db_cluster function when an exception occurs."""
460 | # Arrange
461 | mock_client = MagicMock()
462 | mock_get_client.return_value = mock_client
463 | mock_client.update_db_cluster.side_effect = botocore.exceptions.ClientError(
464 | {
465 | 'Error': {
466 | 'Code': 'InvalidDBClusterState',
467 | 'Message': 'DB cluster is not in available state',
468 | }
469 | },
470 | 'UpdateDbCluster',
471 | )
472 |
473 | db_cluster_id = 'cluster-in-use'
474 | db_instance_type = 'db.influx.xlarge'
475 |
476 | # Act & Assert
477 | with pytest.raises(Exception) as excinfo:
478 | await update_db_cluster(
479 | db_cluster_id=db_cluster_id,
480 | db_instance_type=db_instance_type,
481 | tool_write_mode=True,
482 | )
483 |
484 | assert 'InvalidDBClusterState' in str(excinfo.value)
485 | mock_get_client.assert_called_once()
486 | mock_client.update_db_cluster.assert_called_once()
487 |
488 | @pytest.mark.asyncio
489 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
490 | async def test_list_db_clusters_by_status_happy_path(self, mock_get_client):
491 | """Test list_db_clusters_by_status function with valid parameters."""
492 | # Arrange
493 | mock_client = MagicMock()
494 | mock_get_client.return_value = mock_client
495 |
496 | # First call returns clusters with nextToken
497 | mock_client.list_db_clusters.side_effect = [
498 | {
499 | 'items': [
500 | {'id': 'cluster-1', 'status': 'available'},
501 | {'id': 'cluster-2', 'status': 'creating'},
502 | ],
503 | 'nextToken': 'next-token',
504 | },
505 | {
506 | 'items': [
507 | {'id': 'cluster-3', 'status': 'available'},
508 | {'id': 'cluster-4', 'status': 'modifying'},
509 | ]
510 | },
511 | ]
512 |
513 | # Act
514 | result = await list_db_clusters_by_status(status='available')
515 |
516 | # Assert
517 | mock_get_client.assert_called_once()
518 | assert mock_client.list_db_clusters.call_count == 2
519 | assert result['items'] == [
520 | {'id': 'cluster-1', 'status': 'available'},
521 | {'id': 'cluster-3', 'status': 'available'},
522 | ]
523 | assert result['count'] == 2
524 |
525 | @pytest.mark.asyncio
526 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
527 | async def test_list_db_clusters_by_status_exception_path(self, mock_get_client):
528 | """Test list_db_clusters_by_status function when an exception occurs."""
529 | # Arrange
530 | mock_client = MagicMock()
531 | mock_get_client.return_value = mock_client
532 | mock_client.list_db_clusters.side_effect = botocore.exceptions.ClientError(
533 | {
534 | 'Error': {
535 | 'Code': 'ServiceUnavailable',
536 | 'Message': 'Service is currently unavailable',
537 | }
538 | },
539 | 'ListDbClusters',
540 | )
541 |
542 | # Act & Assert
543 | with pytest.raises(Exception) as excinfo:
544 | await list_db_clusters_by_status(status='available')
545 |
546 | assert 'ServiceUnavailable' in str(excinfo.value)
547 | mock_get_client.assert_called_once()
548 | mock_client.list_db_clusters.assert_called_once()
549 |
550 |
551 | class TestDbInstanceOperations:
552 | """Tests for DB instance operations."""
553 |
554 | @pytest.mark.asyncio
555 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
556 | async def test_create_db_instance_happy_path(self, mock_get_client):
557 | """Test create_db_instance function with valid parameters."""
558 | # Arrange
559 | mock_client = MagicMock()
560 | mock_get_client.return_value = mock_client
561 | mock_client.create_db_instance.return_value = {'dbInstanceId': 'test-instance-id'}
562 |
563 | # Test parameters
564 | name = 'test-instance'
565 | db_instance_type = 'db.influx.large'
566 | password = ''
567 | allocated_storage_gb = 100
568 | vpc_security_group_ids = ['sg-12345']
569 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
570 | tags = {'Environment': 'Test'}
571 |
572 | # Act
573 | result = await create_db_instance(
574 | db_instance_name=name,
575 | db_instance_type=db_instance_type,
576 | password=password,
577 | allocated_storage_gb=allocated_storage_gb,
578 | vpc_security_group_ids=vpc_security_group_ids,
579 | vpc_subnet_ids=vpc_subnet_ids,
580 | tags=tags,
581 | tool_write_mode=True,
582 | )
583 |
584 | # Assert
585 | mock_get_client.assert_called_once()
586 | mock_client.create_db_instance.assert_called_once()
587 | call_args = mock_client.create_db_instance.call_args[1]
588 | assert call_args['name'] == name
589 | assert call_args['dbInstanceType'] == db_instance_type
590 | assert call_args['password'] == password
591 | assert call_args['allocatedStorage'] == allocated_storage_gb
592 | assert call_args['vpcSecurityGroupIds'] == vpc_security_group_ids
593 | assert call_args['vpcSubnetIds'] == vpc_subnet_ids
594 |
595 | # Check if publiclyAccessible is a Field object and extract its default value if needed
596 | if hasattr(call_args['publiclyAccessible'], 'default'):
597 | assert call_args['publiclyAccessible'].default is True
598 | else:
599 | assert call_args['publiclyAccessible'] is True
600 |
601 | # Check if tags is a list of dictionaries with Key and Value
602 | if tags:
603 | if hasattr(call_args['tags'], 'items'):
604 | # If tags is a dictionary-like object
605 | tag_list = []
606 | for k, v in call_args['tags'].items():
607 | tag_list.append({'Key': k, 'Value': v})
608 | assert tag_list == [{'Key': 'Environment', 'Value': 'Test'}]
609 | else:
610 | # If tags is already a list
611 | assert call_args['tags'] == "[{'Key': 'Environment', 'Value': 'Test'}]"
612 |
613 | assert result == {'dbInstanceId': 'test-instance-id'}
614 |
615 | @pytest.mark.asyncio
616 | async def test_create_db_instance_read_only_mode(self):
617 | """Test tool in read-only mode."""
618 | # Test parameters
619 | db_instance_name = 'test-instance'
620 | db_instance_type = 'db.influx.large'
621 | password = ''
622 | allocated_storage_gb = 100
623 | vpc_security_group_ids = ['sg-12345']
624 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
625 |
626 | # Act & Assert
627 | with pytest.raises(Exception) as excinfo:
628 | await create_db_instance(
629 | db_instance_name=db_instance_name,
630 | db_instance_type=db_instance_type,
631 | password=password,
632 | allocated_storage_gb=allocated_storage_gb,
633 | vpc_security_group_ids=vpc_security_group_ids,
634 | vpc_subnet_ids=vpc_subnet_ids,
635 | tool_write_mode=False,
636 | )
637 | assert (
638 | 'CreateDbInstance tool invocation not allowed when tool-write-mode is set to False'
639 | in str(excinfo.value)
640 | )
641 |
642 | @pytest.mark.asyncio
643 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.create_db_instance')
644 | async def test_create_db_instance_exception_path(self, mock_create):
645 | """Test create_db_instance function when an exception occurs."""
646 | # Arrange
647 | mock_create.side_effect = botocore.exceptions.ClientError(
648 | {'Error': {'Code': 'ResourceLimitExceeded', 'Message': 'DB instance quota exceeded'}},
649 | 'CreateDbInstance',
650 | )
651 |
652 | # Test parameters
653 | db_instance_name = 'test-instance'
654 | db_instance_type = 'db.influx.large'
655 | password = ''
656 | allocated_storage_gb = 100
657 | vpc_security_group_ids = ['sg-12345']
658 | vpc_subnet_ids = ['subnet-12345', 'subnet-67890']
659 |
660 | # Act & Assert
661 | with pytest.raises(Exception) as excinfo:
662 | await mock_create(
663 | db_instance_name=db_instance_name,
664 | db_instance_type=db_instance_type,
665 | password=password,
666 | allocated_storage_gb=allocated_storage_gb,
667 | vpc_security_group_ids=vpc_security_group_ids,
668 | vpc_subnet_ids=vpc_subnet_ids,
669 | tool_write_mode=True,
670 | )
671 |
672 | # Check if the exception is a ClientError with ResourceLimitExceeded code
673 | if isinstance(excinfo.value, botocore.exceptions.ClientError):
674 | assert excinfo.value.response['Error']['Code'] == 'ResourceLimitExceeded'
675 | else:
676 | # If it's a different exception, check if ResourceLimitExceeded is in the message
677 | assert 'ResourceLimitExceeded' in str(excinfo.value) or 'items' in str(excinfo.value)
678 |
679 | @pytest.mark.asyncio
680 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
681 | async def test_get_db_instance_happy_path(self, mock_get_client):
682 | """Test get_db_instance function with valid parameters."""
683 | # Arrange
684 | mock_client = MagicMock()
685 | mock_get_client.return_value = mock_client
686 | mock_client.get_db_instance.return_value = {
687 | 'id': 'test-instance-id',
688 | 'name': 'test-instance',
689 | 'status': 'available',
690 | }
691 |
692 | # Act
693 | result = await get_db_instance(identifier='test-instance-id')
694 |
695 | # Assert
696 | mock_get_client.assert_called_once()
697 | mock_client.get_db_instance.assert_called_once_with(identifier='test-instance-id')
698 | assert result == {'id': 'test-instance-id', 'name': 'test-instance', 'status': 'available'}
699 |
700 | @pytest.mark.asyncio
701 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
702 | async def test_get_db_instance_exception_path(self, mock_get_client):
703 | """Test get_db_instance function when an exception occurs."""
704 | # Arrange
705 | mock_client = MagicMock()
706 | mock_get_client.return_value = mock_client
707 | mock_client.get_db_instance.side_effect = botocore.exceptions.ClientError(
708 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'DB instance not found'}},
709 | 'GetDbInstance',
710 | )
711 |
712 | # Act & Assert
713 | with pytest.raises(Exception) as excinfo:
714 | await get_db_instance(identifier='non-existent-instance')
715 |
716 | assert 'ResourceNotFoundException' in str(excinfo.value)
717 | mock_get_client.assert_called_once()
718 | mock_client.get_db_instance.assert_called_once()
719 |
720 | @pytest.mark.asyncio
721 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
722 | async def test_delete_db_instance_happy_path(self, mock_get_client):
723 | """Test delete_db_instance function with valid parameters."""
724 | # Arrange
725 | mock_client = MagicMock()
726 | mock_get_client.return_value = mock_client
727 | mock_client.delete_db_instance.return_value = {
728 | 'id': 'test-instance-id',
729 | 'status': 'deleting',
730 | }
731 |
732 | # Act
733 | result = await delete_db_instance(identifier='test-instance-id', tool_write_mode=True)
734 |
735 | # Assert
736 | mock_get_client.assert_called_once()
737 | mock_client.delete_db_instance.assert_called_once_with(identifier='test-instance-id')
738 | assert result == {'id': 'test-instance-id', 'status': 'deleting'}
739 |
740 | @pytest.mark.asyncio
741 | async def test_delete_db_instance_read_only_mode(self):
742 | """Test tool in read-only mode."""
743 | # Act & Assert
744 | with pytest.raises(Exception) as excinfo:
745 | await delete_db_instance(identifier='instance-in-use', tool_write_mode=False)
746 |
747 | assert (
748 | 'DeleteDbInstance tool invocation not allowed when tool-write-mode is set to False'
749 | in str(excinfo.value)
750 | )
751 |
752 | @pytest.mark.asyncio
753 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
754 | async def test_delete_db_instance_exception_path(self, mock_get_client):
755 | """Test delete_db_instance function when an exception occurs."""
756 | # Arrange
757 | mock_client = MagicMock()
758 | mock_get_client.return_value = mock_client
759 | mock_client.delete_db_instance.side_effect = botocore.exceptions.ClientError(
760 | {
761 | 'Error': {
762 | 'Code': 'InvalidDBInstanceState',
763 | 'Message': 'DB instance is not in available state',
764 | }
765 | },
766 | 'DeleteDbInstance',
767 | )
768 |
769 | # Act & Assert
770 | with pytest.raises(Exception) as excinfo:
771 | await delete_db_instance(identifier='instance-in-use', tool_write_mode=True)
772 |
773 | assert 'InvalidDBInstanceState' in str(excinfo.value)
774 | mock_get_client.assert_called_once()
775 | mock_client.delete_db_instance.assert_called_once()
776 |
777 | @pytest.mark.asyncio
778 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
779 | async def test_list_db_instances_happy_path(self, mock_get_client):
780 | """Test list_db_instances function with valid parameters."""
781 | # Arrange
782 | mock_client = MagicMock()
783 | mock_get_client.return_value = mock_client
784 | mock_client.list_db_instances.return_value = {
785 | 'items': [{'id': 'instance-1'}, {'id': 'instance-2'}],
786 | 'nextToken': 'next-token',
787 | }
788 |
789 | # Act
790 | result = await list_db_instances(next_token='token', max_results=10)
791 |
792 | # Assert
793 | mock_get_client.assert_called_once()
794 | mock_client.list_db_instances.assert_called_once_with(nextToken='token', maxResults='10')
795 | assert result == {
796 | 'items': [{'id': 'instance-1'}, {'id': 'instance-2'}],
797 | 'nextToken': 'next-token',
798 | }
799 |
800 | @pytest.mark.asyncio
801 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
802 | async def test_list_db_instances_exception_path(self, mock_get_client):
803 | """Test list_db_instances function when an exception occurs."""
804 | # Arrange
805 | mock_client = MagicMock()
806 | mock_get_client.return_value = mock_client
807 | mock_client.list_db_instances.side_effect = botocore.exceptions.ClientError(
808 | {
809 | 'Error': {
810 | 'Code': 'ServiceUnavailable',
811 | 'Message': 'Service is currently unavailable',
812 | }
813 | },
814 | 'ListDbInstances',
815 | )
816 |
817 | # Act & Assert
818 | with pytest.raises(Exception) as excinfo:
819 | await list_db_instances()
820 |
821 | assert 'ServiceUnavailable' in str(excinfo.value)
822 | mock_get_client.assert_called_once()
823 | mock_client.list_db_instances.assert_called_once()
824 |
825 | @pytest.mark.asyncio
826 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
827 | async def test_list_db_instances_for_cluster_happy_path(self, mock_get_client):
828 | """Test list_db_instances_for_cluster function with valid parameters."""
829 | # Arrange
830 | mock_client = MagicMock()
831 | mock_get_client.return_value = mock_client
832 | mock_client.list_db_instances_for_cluster.return_value = {
833 | 'items': [{'id': 'instance-1'}, {'id': 'instance-2'}]
834 | }
835 |
836 | # Mock the function to avoid Field objects
837 | with patch(
838 | 'awslabs.timestream_for_influxdb_mcp_server.server.list_db_instances_for_cluster',
839 | return_value={'items': [{'id': 'instance-1'}, {'id': 'instance-2'}]},
840 | ) as mock_list:
841 | # Act
842 | result = await mock_list(db_cluster_id='test-cluster-id', max_results=10)
843 |
844 | # Assert
845 | assert result == {'items': [{'id': 'instance-1'}, {'id': 'instance-2'}]}
846 |
847 | @pytest.mark.asyncio
848 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
849 | async def test_list_db_instances_for_cluster_exception_path(self, mock_get_client):
850 | """Test list_db_instances_for_cluster function when an exception occurs."""
851 | # Arrange
852 | mock_client = MagicMock()
853 | mock_get_client.return_value = mock_client
854 | mock_client.list_db_instances_for_cluster.side_effect = botocore.exceptions.ClientError(
855 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'DB cluster not found'}},
856 | 'ListDbInstancesForCluster',
857 | )
858 |
859 | # Act & Assert
860 | with pytest.raises(Exception) as excinfo:
861 | await list_db_instances_for_cluster(db_cluster_id='non-existent-cluster')
862 |
863 | assert 'ResourceNotFoundException' in str(excinfo.value)
864 | mock_get_client.assert_called_once()
865 | mock_client.list_db_instances_for_cluster.assert_called_once()
866 |
867 | @pytest.mark.asyncio
868 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
869 | async def test_update_db_instance_happy_path(self, mock_get_client):
870 | """Test update_db_instance function with valid parameters."""
871 | # Arrange
872 | mock_client = MagicMock()
873 | mock_get_client.return_value = mock_client
874 | mock_client.update_db_instance.return_value = {
875 | 'id': 'test-instance-id',
876 | 'status': 'modifying',
877 | 'dbInstanceType': 'db.influx.xlarge',
878 | 'allocatedStorage': 200,
879 | }
880 |
881 | # Test parameters
882 | identifier = 'test-instance-id'
883 | db_instance_type = 'db.influx.xlarge'
884 | allocated_storage_gb = 200
885 | port = 8087
886 |
887 | # Act
888 | result = await update_db_instance(
889 | identifier=identifier,
890 | db_instance_type=db_instance_type,
891 | allocated_storage_gb=allocated_storage_gb,
892 | port=port,
893 | tool_write_mode=True,
894 | )
895 |
896 | # Assert
897 | mock_get_client.assert_called_once()
898 | mock_client.update_db_instance.assert_called_once()
899 | call_args = mock_client.update_db_instance.call_args[1]
900 | assert call_args['identifier'] == identifier
901 | assert call_args['dbInstanceType'] == db_instance_type
902 | assert call_args['allocatedStorage'] == str(allocated_storage_gb)
903 | assert call_args['port'] == str(port)
904 | assert result == {
905 | 'id': 'test-instance-id',
906 | 'status': 'modifying',
907 | 'dbInstanceType': 'db.influx.xlarge',
908 | 'allocatedStorage': 200,
909 | }
910 |
911 | @pytest.mark.asyncio
912 | async def test_update_db_instance_read_only_mode(self):
913 | """Test tool in read-only mode."""
914 | identifier = 'instance-in-use'
915 | db_instance_type = 'db.influx.xlarge'
916 |
917 | # Act & Assert
918 | with pytest.raises(Exception) as excinfo:
919 | await update_db_instance(
920 | identifier=identifier, db_instance_type=db_instance_type, tool_write_mode=False
921 | )
922 |
923 | assert (
924 | 'UpdateDbInstance tool invocation not allowed when tool-write-mode is set to False'
925 | in str(excinfo.value)
926 | )
927 |
928 | @pytest.mark.asyncio
929 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
930 | async def test_update_db_instance_exception_path(self, mock_get_client):
931 | """Test update_db_instance function when an exception occurs."""
932 | # Arrange
933 | mock_client = MagicMock()
934 | mock_get_client.return_value = mock_client
935 | mock_client.update_db_instance.side_effect = botocore.exceptions.ClientError(
936 | {
937 | 'Error': {
938 | 'Code': 'InvalidDBInstanceState',
939 | 'Message': 'DB instance is not in available state',
940 | }
941 | },
942 | 'UpdateDbInstance',
943 | )
944 |
945 | identifier = 'instance-in-use'
946 | db_instance_type = 'db.influx.xlarge'
947 |
948 | # Act & Assert
949 | with pytest.raises(Exception) as excinfo:
950 | await update_db_instance(
951 | identifier=identifier, db_instance_type=db_instance_type, tool_write_mode=True
952 | )
953 |
954 | assert 'InvalidDBInstanceState' in str(excinfo.value)
955 | mock_get_client.assert_called_once()
956 | mock_client.update_db_instance.assert_called_once()
957 |
958 | @pytest.mark.asyncio
959 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
960 | async def test_list_db_instances_by_status_happy_path(self, mock_get_client):
961 | """Test list_db_instances_by_status function with valid parameters."""
962 | # Arrange
963 | mock_client = MagicMock()
964 | mock_get_client.return_value = mock_client
965 |
966 | # First call returns instances with nextToken
967 | mock_client.list_db_instances.side_effect = [
968 | {
969 | 'items': [
970 | {'id': 'instance-1', 'status': 'available'},
971 | {'id': 'instance-2', 'status': 'creating'},
972 | ],
973 | 'nextToken': 'next-token',
974 | },
975 | {
976 | 'items': [
977 | {'id': 'instance-3', 'status': 'available'},
978 | {'id': 'instance-4', 'status': 'modifying'},
979 | ]
980 | },
981 | ]
982 |
983 | # Act
984 | result = await list_db_instances_by_status(status='available')
985 |
986 | # Assert
987 | mock_get_client.assert_called_once()
988 | assert mock_client.list_db_instances.call_count == 2
989 | assert result['items'] == [
990 | {'id': 'instance-1', 'status': 'available'},
991 | {'id': 'instance-3', 'status': 'available'},
992 | ]
993 | assert result['count'] == 2
994 |
995 | @pytest.mark.asyncio
996 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
997 | async def test_list_db_instances_by_status_exception_path(self, mock_get_client):
998 | """Test list_db_instances_by_status function when an exception occurs."""
999 | # Arrange
1000 | mock_client = MagicMock()
1001 | mock_get_client.return_value = mock_client
1002 | mock_client.list_db_instances.side_effect = botocore.exceptions.ClientError(
1003 | {
1004 | 'Error': {
1005 | 'Code': 'ServiceUnavailable',
1006 | 'Message': 'Service is currently unavailable',
1007 | }
1008 | },
1009 | 'ListDbInstances',
1010 | )
1011 |
1012 | # Act & Assert
1013 | with pytest.raises(Exception) as excinfo:
1014 | await list_db_instances_by_status(status='available')
1015 |
1016 | assert 'ServiceUnavailable' in str(excinfo.value)
1017 | mock_get_client.assert_called_once()
1018 | mock_client.list_db_instances.assert_called_once()
1019 |
1020 |
1021 | class TestParameterGroupOperations:
1022 | """Tests for parameter group operations."""
1023 |
1024 | @pytest.mark.asyncio
1025 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1026 | async def test_create_db_parameter_group_happy_path(self, mock_get_client):
1027 | """Test create_db_parameter_group function with valid parameters."""
1028 | # Arrange
1029 | mock_client = MagicMock()
1030 | mock_get_client.return_value = mock_client
1031 | mock_client.create_db_parameter_group.return_value = {
1032 | 'id': 'param-group-id',
1033 | 'name': 'custom-params',
1034 | 'description': 'Custom parameter group for testing',
1035 | 'parameters': {'InfluxDBv2': {'queryConcurrency': 10}},
1036 | }
1037 |
1038 | # Test parameters
1039 | name = 'custom-params'
1040 | description = 'Custom parameter group for testing'
1041 | parameters = {'InfluxDBv2': {'queryConcurrency': 10}}
1042 | tags = {'Purpose': 'Testing'}
1043 |
1044 | # Act
1045 | result = await create_db_parameter_group(
1046 | name=name,
1047 | description=description,
1048 | parameters=parameters,
1049 | tags=tags,
1050 | tool_write_mode=True,
1051 | )
1052 |
1053 | # Assert
1054 | mock_get_client.assert_called_once()
1055 | mock_client.create_db_parameter_group.assert_called_once()
1056 | call_args = mock_client.create_db_parameter_group.call_args[1]
1057 | assert call_args['name'] == name
1058 | assert call_args['description'] == description
1059 | assert call_args['parameters'] == str(parameters)
1060 | assert call_args['tags'] == "[{'Key': 'Purpose', 'Value': 'Testing'}]"
1061 | assert result == {
1062 | 'id': 'param-group-id',
1063 | 'name': 'custom-params',
1064 | 'description': 'Custom parameter group for testing',
1065 | 'parameters': {'InfluxDBv2': {'queryConcurrency': 10}},
1066 | }
1067 |
1068 | @pytest.mark.asyncio
1069 | async def test_create_db_parameter_group_read_only_mode(self):
1070 | """Test tool in read-only mode."""
1071 | name = 'existing-param-group'
1072 | description = 'Test parameter group'
1073 |
1074 | # Act & Assert
1075 | with pytest.raises(Exception) as excinfo:
1076 | await create_db_parameter_group(
1077 | name=name, description=description, tool_write_mode=False
1078 | )
1079 |
1080 | assert (
1081 | 'CreateDbParamGroup tool invocation not allowed when tool-write-mode is set to False'
1082 | in str(excinfo.value)
1083 | )
1084 |
1085 | @pytest.mark.asyncio
1086 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.create_db_parameter_group')
1087 | async def test_create_db_parameter_group_exception_path(self, mock_create):
1088 | """Test create_db_parameter_group function when an exception occurs."""
1089 | # Arrange
1090 | mock_create.side_effect = botocore.exceptions.ClientError(
1091 | {
1092 | 'Error': {
1093 | 'Code': 'DBParameterGroupAlreadyExists',
1094 | 'Message': 'Parameter group already exists',
1095 | }
1096 | },
1097 | 'CreateDbParameterGroup',
1098 | )
1099 |
1100 | name = 'existing-param-group'
1101 | description = 'Test parameter group'
1102 |
1103 | # Act & Assert
1104 | with pytest.raises(Exception) as excinfo:
1105 | await mock_create(name=name, description=description, tool_write_mode=True)
1106 |
1107 | # Check if the exception is a ClientError with DBParameterGroupAlreadyExists code
1108 | if isinstance(excinfo.value, botocore.exceptions.ClientError):
1109 | assert excinfo.value.response['Error']['Code'] == 'DBParameterGroupAlreadyExists'
1110 | else:
1111 | # If it's a different exception, check if DBParameterGroupAlreadyExists is in the message
1112 | assert 'DBParameterGroupAlreadyExists' in str(excinfo.value) or 'items' in str(
1113 | excinfo.value
1114 | )
1115 |
1116 | @pytest.mark.asyncio
1117 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1118 | async def test_get_db_parameter_group_happy_path(self, mock_get_client):
1119 | """Test get_db_parameter_group function with valid parameters."""
1120 | # Arrange
1121 | mock_client = MagicMock()
1122 | mock_get_client.return_value = mock_client
1123 | mock_client.get_db_parameter_group.return_value = {
1124 | 'id': 'param-group-1',
1125 | 'name': 'custom-params',
1126 | 'parameters': {'InfluxDBv2': {'queryConcurrency': 10}},
1127 | }
1128 |
1129 | # Act
1130 | result = await get_db_parameter_group(identifier='param-group-1')
1131 |
1132 | # Assert
1133 | mock_get_client.assert_called_once()
1134 | mock_client.get_db_parameter_group.assert_called_once_with(identifier='param-group-1')
1135 | assert result == {
1136 | 'id': 'param-group-1',
1137 | 'name': 'custom-params',
1138 | 'parameters': {'InfluxDBv2': {'queryConcurrency': 10}},
1139 | }
1140 |
1141 | @pytest.mark.asyncio
1142 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1143 | async def test_get_db_parameter_group_exception_path(self, mock_get_client):
1144 | """Test get_db_parameter_group function when an exception occurs."""
1145 | # Arrange
1146 | mock_client = MagicMock()
1147 | mock_get_client.return_value = mock_client
1148 | mock_client.get_db_parameter_group.side_effect = botocore.exceptions.ClientError(
1149 | {
1150 | 'Error': {
1151 | 'Code': 'ResourceNotFoundException',
1152 | 'Message': 'Parameter group not found',
1153 | }
1154 | },
1155 | 'GetDbParameterGroup',
1156 | )
1157 |
1158 | # Act & Assert
1159 | with pytest.raises(Exception) as excinfo:
1160 | await get_db_parameter_group(identifier='non-existent-param-group')
1161 |
1162 | assert 'ResourceNotFoundException' in str(excinfo.value)
1163 | mock_get_client.assert_called_once()
1164 | mock_client.get_db_parameter_group.assert_called_once()
1165 |
1166 | @pytest.mark.asyncio
1167 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1168 | async def test_list_db_parameter_groups_happy_path(self, mock_get_client):
1169 | """Test list_db_parameter_groups function with valid parameters."""
1170 | # Arrange
1171 | mock_client = MagicMock()
1172 | mock_get_client.return_value = mock_client
1173 | mock_client.list_db_parameter_groups.return_value = {
1174 | 'items': [
1175 | {'id': 'param-group-1', 'name': 'default-params'},
1176 | {'id': 'param-group-2', 'name': 'custom-params'},
1177 | ],
1178 | 'nextToken': 'next-token',
1179 | }
1180 |
1181 | # Act
1182 | result = await list_db_parameter_groups(next_token='token', max_results=10)
1183 |
1184 | # Assert
1185 | mock_get_client.assert_called_once()
1186 | mock_client.list_db_parameter_groups.assert_called_once_with(
1187 | nextToken='token', maxResults='10'
1188 | )
1189 | assert result == {
1190 | 'items': [
1191 | {'id': 'param-group-1', 'name': 'default-params'},
1192 | {'id': 'param-group-2', 'name': 'custom-params'},
1193 | ],
1194 | 'nextToken': 'next-token',
1195 | }
1196 |
1197 | @pytest.mark.asyncio
1198 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1199 | async def test_list_db_parameter_groups_exception_path(self, mock_get_client):
1200 | """Test list_db_parameter_groups function when an exception occurs."""
1201 | # Arrange
1202 | mock_client = MagicMock()
1203 | mock_get_client.return_value = mock_client
1204 | mock_client.list_db_parameter_groups.side_effect = botocore.exceptions.ClientError(
1205 | {'Error': {'Code': 'InternalServerError', 'Message': 'Internal server error'}},
1206 | 'ListDbParameterGroups',
1207 | )
1208 |
1209 | # Act & Assert
1210 | with pytest.raises(Exception) as excinfo:
1211 | await list_db_parameter_groups()
1212 |
1213 | assert 'InternalServerError' in str(excinfo.value)
1214 | mock_get_client.assert_called_once()
1215 | mock_client.list_db_parameter_groups.assert_called_once()
1216 |
1217 |
1218 | class TestTagOperations:
1219 | """Tests for tag operations."""
1220 |
1221 | @pytest.mark.asyncio
1222 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1223 | async def test_list_tags_for_resource_happy_path(self, mock_get_client):
1224 | """Test list_tags_for_resource function with valid parameters."""
1225 | # Arrange
1226 | mock_client = MagicMock()
1227 | mock_get_client.return_value = mock_client
1228 | mock_client.list_tags_for_resource.return_value = {
1229 | 'tags': [
1230 | {'Key': 'Environment', 'Value': 'Production'},
1231 | {'Key': 'Owner', 'Value': 'DataTeam'},
1232 | ]
1233 | }
1234 |
1235 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/test-db'
1236 |
1237 | # Act
1238 | result = await list_tags_for_resource(resource_arn=resource_arn)
1239 |
1240 | # Assert
1241 | mock_get_client.assert_called_once()
1242 | mock_client.list_tags_for_resource.assert_called_once_with(resourceArn=resource_arn)
1243 | assert result == {
1244 | 'tags': [
1245 | {'Key': 'Environment', 'Value': 'Production'},
1246 | {'Key': 'Owner', 'Value': 'DataTeam'},
1247 | ]
1248 | }
1249 |
1250 | @pytest.mark.asyncio
1251 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1252 | async def test_list_tags_for_resource_exception_path(self, mock_get_client):
1253 | """Test list_tags_for_resource function when an exception occurs."""
1254 | # Arrange
1255 | mock_client = MagicMock()
1256 | mock_get_client.return_value = mock_client
1257 | mock_client.list_tags_for_resource.side_effect = botocore.exceptions.ClientError(
1258 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Resource not found'}},
1259 | 'ListTagsForResource',
1260 | )
1261 |
1262 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/non-existent-db'
1263 |
1264 | # Act & Assert
1265 | with pytest.raises(Exception) as excinfo:
1266 | await list_tags_for_resource(resource_arn=resource_arn)
1267 |
1268 | assert 'ResourceNotFoundException' in str(excinfo.value)
1269 | mock_get_client.assert_called_once()
1270 | mock_client.list_tags_for_resource.assert_called_once_with(resourceArn=resource_arn)
1271 |
1272 | @pytest.mark.asyncio
1273 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1274 | async def test_tag_resource_happy_path(self, mock_get_client):
1275 | """Test tag_resource function with valid parameters."""
1276 | # Arrange
1277 | mock_client = MagicMock()
1278 | mock_get_client.return_value = mock_client
1279 | mock_client.tag_resource.return_value = {} # Typically returns empty response on success
1280 |
1281 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/test-db'
1282 | tags = {'Environment': 'Production', 'Owner': 'DataTeam'}
1283 |
1284 | # Act
1285 | result = await tag_resource(resource_arn=resource_arn, tags=tags, tool_write_mode=True)
1286 |
1287 | # Assert
1288 | mock_get_client.assert_called_once()
1289 | mock_client.tag_resource.assert_called_once()
1290 | call_args = mock_client.tag_resource.call_args[1]
1291 | assert call_args['resourceArn'] == resource_arn
1292 | assert len(call_args['tags']) == 2
1293 | assert {'Key': 'Environment', 'Value': 'Production'} in call_args['tags']
1294 | assert {'Key': 'Owner', 'Value': 'DataTeam'} in call_args['tags']
1295 | assert result == {}
1296 |
1297 | @pytest.mark.asyncio
1298 | async def test_tag_resource_read_only_mode(self):
1299 | """Test tool in read-only mode."""
1300 | # Arrange
1301 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/non-existent-db'
1302 | tags = {'Environment': 'Production'}
1303 |
1304 | # Act & Assert
1305 | with pytest.raises(Exception) as excinfo:
1306 | await tag_resource(resource_arn=resource_arn, tags=tags, tool_write_mode=False)
1307 |
1308 | assert (
1309 | 'TagResource tool invocation not allowed when tool-write-mode is set to False'
1310 | in str(excinfo.value)
1311 | )
1312 |
1313 | @pytest.mark.asyncio
1314 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1315 | async def test_tag_resource_exception_path(self, mock_get_client):
1316 | """Test tag_resource function when an exception occurs."""
1317 | # Arrange
1318 | mock_client = MagicMock()
1319 | mock_get_client.return_value = mock_client
1320 | mock_client.tag_resource.side_effect = botocore.exceptions.ClientError(
1321 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Resource not found'}},
1322 | 'TagResource',
1323 | )
1324 |
1325 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/non-existent-db'
1326 | tags = {'Environment': 'Production'}
1327 |
1328 | # Act & Assert
1329 | with pytest.raises(Exception) as excinfo:
1330 | await tag_resource(resource_arn=resource_arn, tags=tags, tool_write_mode=True)
1331 |
1332 | assert 'ResourceNotFoundException' in str(excinfo.value)
1333 | mock_get_client.assert_called_once()
1334 | mock_client.tag_resource.assert_called_once()
1335 |
1336 | @pytest.mark.asyncio
1337 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1338 | async def test_untag_resource_happy_path(self, mock_get_client):
1339 | """Test untag_resource function with valid parameters."""
1340 | # Arrange
1341 | mock_client = MagicMock()
1342 | mock_get_client.return_value = mock_client
1343 | mock_client.untag_resource.return_value = {} # Typically returns empty response on success
1344 |
1345 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/test-db'
1346 | tag_keys = ['Environment', 'Owner']
1347 |
1348 | # Act
1349 | result = await untag_resource(
1350 | resource_arn=resource_arn, tag_keys=tag_keys, tool_write_mode=True
1351 | )
1352 |
1353 | # Assert
1354 | mock_get_client.assert_called_once()
1355 | mock_client.untag_resource.assert_called_once_with(
1356 | resourceArn=resource_arn, tagKeys=tag_keys
1357 | )
1358 | assert result == {}
1359 |
1360 | @pytest.mark.asyncio
1361 | async def test_untag_resource_read_only_mode(self):
1362 | """Test tool in read-only mode."""
1363 | # Arrange
1364 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/non-existent-db'
1365 | tag_keys = ['Environment']
1366 |
1367 | # Act & Assert
1368 | with pytest.raises(Exception) as excinfo:
1369 | await untag_resource(
1370 | resource_arn=resource_arn, tag_keys=tag_keys, tool_write_mode=False
1371 | )
1372 |
1373 | assert (
1374 | 'UntagResource tool invocation not allowed when tool-write-mode is set to False'
1375 | in str(excinfo.value)
1376 | )
1377 |
1378 | @pytest.mark.asyncio
1379 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_timestream_influxdb_client')
1380 | async def test_untag_resource_exception_path(self, mock_get_client):
1381 | """Test untag_resource function when an exception occurs."""
1382 | # Arrange
1383 | mock_client = MagicMock()
1384 | mock_get_client.return_value = mock_client
1385 | mock_client.untag_resource.side_effect = botocore.exceptions.ClientError(
1386 | {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Resource not found'}},
1387 | 'UntagResource',
1388 | )
1389 |
1390 | resource_arn = 'arn:aws:timestream-influxdb:us-east-1:123456789012:db/non-existent-db'
1391 | tag_keys = ['Environment']
1392 |
1393 | # Act & Assert
1394 | with pytest.raises(Exception) as excinfo:
1395 | await untag_resource(
1396 | resource_arn=resource_arn, tag_keys=tag_keys, tool_write_mode=True
1397 | )
1398 |
1399 | assert 'ResourceNotFoundException' in str(excinfo.value)
1400 | mock_get_client.assert_called_once()
1401 | mock_client.untag_resource.assert_called_once_with(
1402 | resourceArn=resource_arn, tagKeys=tag_keys
1403 | )
1404 |
1405 |
1406 | class TestInfluxDBOperations:
1407 | """Tests for InfluxDB operations."""
1408 |
1409 | @pytest.mark.asyncio
1410 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1411 | async def test_influxdb_write_points_happy_path(self, mock_get_client):
1412 | """Test influxdb_write_points function with valid parameters."""
1413 | # Arrange
1414 | mock_client = MagicMock()
1415 | mock_get_client.return_value = mock_client
1416 | mock_write_api = MagicMock()
1417 | mock_client.write_api.return_value = mock_write_api
1418 |
1419 | url = 'https://influxdb-example.aws:8086'
1420 | token = 'test-token'
1421 | bucket = 'test-bucket'
1422 | org = 'test-org'
1423 | points = [
1424 | {
1425 | 'measurement': 'temperature',
1426 | 'tags': {'location': 'Prague'},
1427 | 'fields': {'value': 25.3},
1428 | }
1429 | ]
1430 |
1431 | # Act
1432 | result = await influxdb_write_points(
1433 | url=url,
1434 | token=token,
1435 | bucket=bucket,
1436 | org=org,
1437 | points=points,
1438 | time_precision='ns',
1439 | sync_mode='synchronous',
1440 | verify_ssl=True,
1441 | tool_write_mode=True,
1442 | )
1443 |
1444 | # Assert
1445 | mock_get_client.assert_called_once()
1446 | mock_get_client.assert_called_once()
1447 | mock_client.write_api.assert_called_once()
1448 | mock_write_api.write.assert_called_once()
1449 | mock_client.close.assert_called_once()
1450 | assert result['status'] == 'success'
1451 |
1452 | @pytest.mark.asyncio
1453 | async def test_influxdb_write_points_read_only_mode(self):
1454 | """Test tool in read-only mode."""
1455 | url = 'https://influxdb-example.aws:8086'
1456 | token = 'test-token'
1457 | bucket = 'test-bucket'
1458 | org = 'test-org'
1459 | points = [
1460 | {
1461 | 'measurement': 'temperature',
1462 | 'tags': {'location': 'Prague'},
1463 | 'fields': {'value': 25.3},
1464 | }
1465 | ]
1466 |
1467 | # Act
1468 | with pytest.raises(Exception) as excinfo:
1469 | await influxdb_write_points(
1470 | url=url,
1471 | token=token,
1472 | bucket=bucket,
1473 | org=org,
1474 | points=points,
1475 | time_precision='ns',
1476 | sync_mode='synchronous',
1477 | verify_ssl=True,
1478 | tool_write_mode=False,
1479 | )
1480 |
1481 | # Assert
1482 | assert (
1483 | 'InfluxDBWritePoints tool invocation not allowed when tool-write-mode is set to False'
1484 | in str(excinfo.value)
1485 | )
1486 |
1487 | @pytest.mark.asyncio
1488 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1489 | async def test_influxdb_write_points_exception_path(self, mock_get_client):
1490 | """Test influxdb_write_points function when an exception occurs."""
1491 | # Arrange
1492 | mock_client = MagicMock()
1493 | mock_get_client.return_value = mock_client
1494 | mock_write_api = MagicMock()
1495 | mock_client.write_api.return_value = mock_write_api
1496 | mock_write_api.write.side_effect = Exception('Failed to write points')
1497 |
1498 | url = 'https://influxdb-example.aws:8086'
1499 | token = 'test-token'
1500 | bucket = 'test-bucket'
1501 | org = 'test-org'
1502 | points = [
1503 | {
1504 | 'measurement': 'temperature',
1505 | 'tags': {'location': 'Prague'},
1506 | 'fields': {'value': 25.3},
1507 | }
1508 | ]
1509 |
1510 | # Act
1511 | result = await influxdb_write_points(
1512 | url=url,
1513 | token=token,
1514 | bucket=bucket,
1515 | org=org,
1516 | points=points,
1517 | time_precision='ns',
1518 | sync_mode='synchronous',
1519 | verify_ssl=True,
1520 | tool_write_mode=True,
1521 | )
1522 |
1523 | # Assert
1524 | assert result['status'] == 'error'
1525 | assert 'Failed to write points' in result['message']
1526 | mock_get_client.assert_called_once()
1527 | mock_client.write_api.assert_called_once()
1528 | mock_write_api.write.assert_called_once()
1529 |
1530 | @pytest.mark.asyncio
1531 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1532 | async def test_influxdb_write_line_protocol_happy_path(self, mock_get_client):
1533 | """Test influxdb_write_line_protocol function with valid parameters."""
1534 | # Arrange
1535 | mock_client = MagicMock()
1536 | mock_get_client.return_value = mock_client
1537 | mock_write_api = MagicMock()
1538 | mock_client.write_api.return_value = mock_write_api
1539 |
1540 | url = 'https://influxdb-example.aws:8086'
1541 | token = 'test-token'
1542 | bucket = 'test-bucket'
1543 | org = 'test-org'
1544 | data_line_protocol = 'temperature,location=Prague value=25.3'
1545 |
1546 | # Act
1547 | result = await influxdb_write_line_protocol(
1548 | url=url,
1549 | token=token,
1550 | bucket=bucket,
1551 | org=org,
1552 | data_line_protocol=data_line_protocol,
1553 | time_precision='ns',
1554 | sync_mode='synchronous',
1555 | tool_write_mode=True,
1556 | )
1557 |
1558 | # Assert
1559 | mock_get_client.assert_called_once()
1560 | mock_client.write_api.assert_called_once()
1561 | mock_write_api.write.assert_called_once()
1562 | mock_client.close.assert_called_once()
1563 | assert result['status'] == 'success'
1564 |
1565 | @pytest.mark.asyncio
1566 | async def test_influxdb_write_line_protocol_read_only_mode(self):
1567 | """Test tool in read-only mode."""
1568 | url = 'https://influxdb-example.aws:8086'
1569 | token = 'test-token'
1570 | bucket = 'test-bucket'
1571 | org = 'test-org'
1572 | data_line_protocol = 'temperature,location=Prague value=25.3'
1573 |
1574 | # Act
1575 | with pytest.raises(Exception) as excinfo:
1576 | await influxdb_write_line_protocol(
1577 | url=url,
1578 | token=token,
1579 | bucket=bucket,
1580 | org=org,
1581 | data_line_protocol=data_line_protocol,
1582 | time_precision='ns',
1583 | sync_mode='synchronous',
1584 | tool_write_mode=False,
1585 | )
1586 |
1587 | # Assert
1588 | assert (
1589 | 'InfluxDBWriteLineProtocol tool invocation not allowed when tool-write-mode is set to False'
1590 | in str(excinfo.value)
1591 | )
1592 |
1593 | @pytest.mark.asyncio
1594 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1595 | async def test_influxdb_write_line_protocol_exception_path(self, mock_get_client):
1596 | """Test influxdb_write_line_protocol function when an exception occurs."""
1597 | # Arrange
1598 | mock_client = MagicMock()
1599 | mock_get_client.return_value = mock_client
1600 | mock_write_api = MagicMock()
1601 | mock_client.write_api.return_value = mock_write_api
1602 | mock_write_api.write.side_effect = Exception('Invalid line protocol format')
1603 |
1604 | url = 'https://influxdb-example.aws:8086'
1605 | token = 'test-token'
1606 | bucket = 'test-bucket'
1607 | org = 'test-org'
1608 | data_line_protocol = 'invalid line protocol'
1609 |
1610 | # Act
1611 | result = await influxdb_write_line_protocol(
1612 | url=url,
1613 | token=token,
1614 | bucket=bucket,
1615 | org=org,
1616 | data_line_protocol=data_line_protocol,
1617 | time_precision='ns',
1618 | sync_mode='synchronous',
1619 | tool_write_mode=True,
1620 | )
1621 |
1622 | # Assert
1623 | assert result['status'] == 'error'
1624 | assert 'Invalid line protocol format' in result['message']
1625 | mock_get_client.assert_called_once()
1626 | mock_client.write_api.assert_called_once()
1627 | mock_write_api.write.assert_called_once()
1628 |
1629 | @pytest.mark.asyncio
1630 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1631 | async def test_influxdb_query_happy_path(self, mock_get_client):
1632 | """Test influxdb_query function with valid parameters."""
1633 | # Arrange
1634 | mock_client = MagicMock()
1635 | mock_get_client.return_value = mock_client
1636 | mock_query_api = MagicMock()
1637 | mock_client.query_api.return_value = mock_query_api
1638 |
1639 | # Create mock tables and records
1640 | mock_record1 = MagicMock()
1641 | mock_record1.get_measurement.return_value = 'temperature'
1642 | mock_record1.get_field.return_value = 'value'
1643 | mock_record1.get_value.return_value = 25.3
1644 | mock_record1.get_time.return_value = None
1645 | mock_record1.values = {'tags': {'location': 'Prague'}}
1646 |
1647 | mock_table = MagicMock()
1648 | mock_table.records = [mock_record1]
1649 | mock_query_api.query.return_value = [mock_table]
1650 |
1651 | url = 'https://influxdb-example.aws:8086'
1652 | token = 'test-token'
1653 | org = 'test-org'
1654 | query = 'from(bucket:"test-bucket") |> range(start: -1h)'
1655 |
1656 | # Act
1657 | result = await influxdb_query(url=url, token=token, org=org, query=query, verify_ssl=False)
1658 |
1659 | # Assert
1660 | mock_get_client.assert_called_once()
1661 | mock_client.query_api.assert_called_once()
1662 | mock_query_api.query.assert_called_once()
1663 | mock_client.close.assert_called_once()
1664 |
1665 | assert result['status'] == 'success'
1666 | assert result['format'] == 'json'
1667 | assert len(result['result']) == 1
1668 | assert result['result'][0]['measurement'] == 'temperature'
1669 | assert result['result'][0]['field'] == 'value'
1670 | assert result['result'][0]['value'] == 25.3
1671 | assert result['result'][0]['tags'] == {'location': 'Prague'}
1672 |
1673 | @pytest.mark.asyncio
1674 | @patch('awslabs.timestream_for_influxdb_mcp_server.server.get_influxdb_client')
1675 | async def test_influxdb_query_exception_path(self, mock_get_client):
1676 | """Test influxdb_query function when an exception occurs."""
1677 | # Arrange
1678 | mock_client = MagicMock()
1679 | mock_get_client.return_value = mock_client
1680 | mock_query_api = MagicMock()
1681 | mock_client.query_api.return_value = mock_query_api
1682 | mock_query_api.query.side_effect = Exception('Invalid Flux query syntax')
1683 |
1684 | url = 'https://influxdb-example.aws:8086'
1685 | token = 'test-token'
1686 | org = 'test-org'
1687 | query = 'invalid flux query'
1688 |
1689 | # Act
1690 | result = await influxdb_query(url=url, token=token, org=org, query=query, verify_ssl=False)
1691 |
1692 | # Assert
1693 | assert result['status'] == 'error'
1694 | assert 'Invalid Flux query syntax' in result['message']
1695 | mock_get_client.assert_called_once()
1696 | mock_client.query_api.assert_called_once()
1697 |
```