#
tokens: 61783/50000 1/2431 files (page 381/384)
lines: off (toggle) GitHub
raw markdown copy
This is page 381 of 384. Use http://codebase.md/awslabs/mcp?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
├── src
│   ├── amazon-bedrock-agentcore-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_bedrock_agentcore_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── config.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── cache.py
│   │   │           ├── doc_fetcher.py
│   │   │           ├── indexer.py
│   │   │           ├── text_processor.py
│   │   │           └── url_validator.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── SECURITY.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_cache.py
│   │   │   ├── test_config.py
│   │   │   ├── test_doc_fetcher.py
│   │   │   ├── test_indexer.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_server.py
│   │   │   ├── test_text_processor.py
│   │   │   └── test_url_validator.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── amazon-kendra-index-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_kendra_index_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── util.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── amazon-keyspaces-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_keyspaces_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── client.py
│   │   │       ├── config.py
│   │   │       ├── consts.py
│   │   │       ├── llm_context.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── services.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_client.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_query_analysis_service.py
│   │   │   ├── test_server.py
│   │   │   └── test_services.py
│   │   └── uv.lock
│   ├── amazon-mq-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_mq_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_service_mcp_generator.py
│   │   │       ├── consts.py
│   │   │       ├── rabbitmq
│   │   │       │   ├── __init__.py
│   │   │       │   ├── admin.py
│   │   │       │   ├── connection.py
│   │   │       │   ├── doc
│   │   │       │   │   ├── rabbitmq_broker_sizing_guide.md
│   │   │       │   │   ├── rabbitmq_performance_optimization_best_practice.md
│   │   │       │   │   ├── rabbitmq_production_deployment_guidelines.md
│   │   │       │   │   ├── rabbitmq_quorum_queue_migration_guide.md
│   │   │       │   │   └── rabbitmq_setup_best_practice.md
│   │   │       │   ├── handlers.py
│   │   │       │   └── module.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── example
│   │   │   └── sample_mcp_q_cli.json
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── rabbitmq
│   │   │   │   ├── __init__.py
│   │   │   │   ├── conftest.py
│   │   │   │   ├── test_admin.py
│   │   │   │   ├── test_connection.py
│   │   │   │   ├── test_handlers.py
│   │   │   │   └── test_module.py
│   │   │   ├── test_aws_service_mcp_generator.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── amazon-neptune-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_neptune_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── exceptions.py
│   │   │       ├── graph_store
│   │   │       │   ├── __init__.py
│   │   │       │   ├── analytics.py
│   │   │       │   ├── base.py
│   │   │       │   └── database.py
│   │   │       ├── models.py
│   │   │       ├── neptune.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_analytics.py
│   │   │   ├── test_database.py
│   │   │   ├── test_exceptions.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_neptune.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── amazon-qbusiness-anonymous-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_qbusiness_anonymous_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── clients.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── amazon-qindex-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_qindex_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── clients.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_clients.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   └── uv.lock
│   ├── amazon-sns-sqs-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── amazon_sns_sqs_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common.py
│   │   │       ├── consts.py
│   │   │       ├── generator.py
│   │   │       ├── server.py
│   │   │       ├── sns.py
│   │   │       └── sqs.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── print_tools.py
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── test_common.py
│   │   │   ├── test_generator.py
│   │   │   ├── test_server.py
│   │   │   ├── test_sns.py
│   │   │   └── test_sqs.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aurora-dsql-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aurora_dsql_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── mutable_sql_detector.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_connection_reuse.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_profile_option.py
│   │   │   ├── test_readonly_enforcement.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-api-mcp-server
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_api_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── core
│   │   │       │   ├── __init__.py
│   │   │       │   ├── agent_scripts
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── manager.py
│   │   │       │   │   ├── models.py
│   │   │       │   │   └── registry
│   │   │       │   │       ├── __init__.py
│   │   │       │   │       ├── application-failure-troubleshooting.script.md
│   │   │       │   │       ├── cloudtral-mutli-region-setup.script.md
│   │   │       │   │       ├── create_amazon_aurora_db_cluster_with_instances.script.md
│   │   │       │   │       ├── lambda-timeout-debugging.script.md
│   │   │       │   │       ├── scripts_format.md
│   │   │       │   │       └── troubleshoot-permissions-with-cloudtrail-events.script.md
│   │   │       │   ├── aws
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── driver.py
│   │   │       │   │   ├── pagination.py
│   │   │       │   │   ├── regions.py
│   │   │       │   │   ├── service.py
│   │   │       │   │   └── services.py
│   │   │       │   ├── common
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── command_metadata.py
│   │   │       │   │   ├── command.py
│   │   │       │   │   ├── config.py
│   │   │       │   │   ├── errors.py
│   │   │       │   │   ├── file_operations.py
│   │   │       │   │   ├── file_system_controls.py
│   │   │       │   │   ├── helpers.py
│   │   │       │   │   ├── models.py
│   │   │       │   │   └── py.typed
│   │   │       │   ├── data
│   │   │       │   │   └── api_metadata.json
│   │   │       │   ├── metadata
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   └── read_only_operations_list.py
│   │   │       │   ├── parser
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── custom_validators
│   │   │       │   │   │   ├── __init__.py
│   │   │       │   │   │   ├── botocore_param_validator.py
│   │   │       │   │   │   ├── ec2_validator.py
│   │   │       │   │   │   └── ssm_validator.py
│   │   │       │   │   ├── interpretation.py
│   │   │       │   │   ├── lexer.py
│   │   │       │   │   └── parser.py
│   │   │       │   ├── py.typed
│   │   │       │   └── security
│   │   │       │       ├── __init__.py
│   │   │       │       ├── aws_api_customization.json
│   │   │       │       └── policy.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── agent_scripts
│   │   │   │   ├── __init__.py
│   │   │   │   ├── test_manager.py
│   │   │   │   └── test_registry
│   │   │   │       ├── another_valid_script.script.md
│   │   │   │       ├── test_script.script.md
│   │   │   │       └── valid_script.script.md
│   │   │   ├── aws
│   │   │   │   ├── __init__.py
│   │   │   │   ├── test_driver.py
│   │   │   │   ├── test_pagination.py
│   │   │   │   ├── test_service.py
│   │   │   │   └── test_services.py
│   │   │   ├── common
│   │   │   │   ├── test_command.py
│   │   │   │   ├── test_config.py
│   │   │   │   ├── test_file_operations.py
│   │   │   │   ├── test_file_system_controls.py
│   │   │   │   ├── test_file_validation.py
│   │   │   │   └── test_helpers.py
│   │   │   ├── fixtures.py
│   │   │   ├── history_handler.py
│   │   │   ├── metadata
│   │   │   │   ├── __init__.py
│   │   │   │   └── test_read_only_operations_list.py
│   │   │   ├── parser
│   │   │   │   ├── __init__.py
│   │   │   │   ├── test_file_path_detection.py
│   │   │   │   ├── test_lexer.py
│   │   │   │   ├── test_parser_customizations.py
│   │   │   │   └── test_parser.py
│   │   │   ├── test_security_policy.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-appsync-mcp-server
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_appsync_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── decorators.py
│   │   │       ├── helpers.py
│   │   │       ├── operations
│   │   │       │   ├── __init__.py
│   │   │       │   ├── create_api_cache.py
│   │   │       │   ├── create_api_key.py
│   │   │       │   ├── create_api.py
│   │   │       │   ├── create_channel_namespace.py
│   │   │       │   ├── create_datasource.py
│   │   │       │   ├── create_domain_name.py
│   │   │       │   ├── create_function.py
│   │   │       │   ├── create_graphql_api.py
│   │   │       │   ├── create_resolver.py
│   │   │       │   └── create_schema.py
│   │   │       ├── server.py
│   │   │       ├── tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── create_api_cache.py
│   │   │       │   ├── create_api_key.py
│   │   │       │   ├── create_api.py
│   │   │       │   ├── create_channel_namespace.py
│   │   │       │   ├── create_datasource.py
│   │   │       │   ├── create_domain_name.py
│   │   │       │   ├── create_function.py
│   │   │       │   ├── create_graphql_api.py
│   │   │       │   ├── create_resolver.py
│   │   │       │   └── create_schema.py
│   │   │       └── validators.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_all_create_tools_write_protection.py
│   │   │   ├── test_create_api_cache.py
│   │   │   ├── test_create_api_key.py
│   │   │   ├── test_create_api.py
│   │   │   ├── test_create_channel_namespace.py
│   │   │   ├── test_create_datasource_tool.py
│   │   │   ├── test_create_datasource.py
│   │   │   ├── test_create_domain_name.py
│   │   │   ├── test_create_function.py
│   │   │   ├── test_create_graphql_api.py
│   │   │   ├── test_create_resolver.py
│   │   │   ├── test_create_schema_tool.py
│   │   │   ├── test_create_schema.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_server.py
│   │   │   ├── test_validators.py
│   │   │   └── test_write_operation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-bedrock-custom-model-import-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_bedrock_custom_model_import_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── client.py
│   │   │       ├── llm_context.py
│   │   │       ├── models.py
│   │   │       ├── prompts.py
│   │   │       ├── server.py
│   │   │       ├── services
│   │   │       │   ├── __init__.py
│   │   │       │   ├── imported_model_service.py
│   │   │       │   └── model_import_service.py
│   │   │       ├── tools
│   │   │       │   ├── create_model_import_job.py
│   │   │       │   ├── delete_imported_model.py
│   │   │       │   ├── get_imported_model.py
│   │   │       │   ├── get_model_import_job.py
│   │   │       │   ├── list_imported_models.py
│   │   │       │   └── list_model_import_jobs.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── aws.py
│   │   │           ├── config.py
│   │   │           ├── consts.py
│   │   │           └── matching.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── services
│   │   │   │   ├── test_imported_model_service.py
│   │   │   │   └── test_model_import_service.py
│   │   │   ├── test_client.py
│   │   │   ├── test_init.py
│   │   │   ├── test_llm_context.py
│   │   │   ├── test_prompts.py
│   │   │   ├── test_server.py
│   │   │   ├── tools
│   │   │   │   ├── test_create_model_import_job.py
│   │   │   │   ├── test_delete_imported_model.py
│   │   │   │   ├── test_get_imported_model.py
│   │   │   │   ├── test_get_model_import_job.py
│   │   │   │   ├── test_list_imported_models.py
│   │   │   │   └── test_list_model_import_jobs.py
│   │   │   └── utils
│   │   │       ├── test_aws.py
│   │   │       ├── test_config.py
│   │   │       └── test_matching.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-bedrock-data-automation-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_bedrock_data_automation_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── helpers.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-dataprocessing-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_dataprocessing_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── core
│   │   │       │   ├── __init__.py
│   │   │       │   └── glue_data_catalog
│   │   │       │       ├── __init__.py
│   │   │       │       ├── data_catalog_database_manager.py
│   │   │       │       ├── data_catalog_handler.py
│   │   │       │       └── data_catalog_table_manager.py
│   │   │       ├── handlers
│   │   │       │   ├── __init__.py
│   │   │       │   ├── athena
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── athena_data_catalog_handler.py
│   │   │       │   │   ├── athena_query_handler.py
│   │   │       │   │   └── athena_workgroup_handler.py
│   │   │       │   ├── commons
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   └── common_resource_handler.py
│   │   │       │   ├── emr
│   │   │       │   │   ├── emr_ec2_cluster_handler.py
│   │   │       │   │   ├── emr_ec2_instance_handler.py
│   │   │       │   │   └── emr_ec2_steps_handler.py
│   │   │       │   └── glue
│   │   │       │       ├── __init__.py
│   │   │       │       ├── crawler_handler.py
│   │   │       │       ├── data_catalog_handler.py
│   │   │       │       ├── glue_commons_handler.py
│   │   │       │       ├── glue_etl_handler.py
│   │   │       │       ├── interactive_sessions_handler.py
│   │   │       │       └── worklows_handler.py
│   │   │       ├── models
│   │   │       │   ├── __init__.py
│   │   │       │   ├── athena_models.py
│   │   │       │   ├── common_resource_models.py
│   │   │       │   ├── data_catalog_models.py
│   │   │       │   ├── emr_models.py
│   │   │       │   └── glue_models.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── aws_helper.py
│   │   │           ├── consts.py
│   │   │           ├── logging_helper.py
│   │   │           └── mutable_sql_detector.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
│   │   ├── 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
│   │   │       ├── prompts
│   │   │       │   ├── __init__.py
│   │   │       │   ├── asset_hierarchy.py
│   │   │       │   ├── data_exploration.py
│   │   │       │   └── data_ingestion.py
│   │   │       ├── server.py
│   │   │       ├── tool_metadata.py
│   │   │       ├── tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── sitewise_access.py
│   │   │       │   ├── sitewise_asset_models.py
│   │   │       │   ├── sitewise_assets.py
│   │   │       │   ├── sitewise_data.py
│   │   │       │   └── sitewise_gateways.py
│   │   │       └── validation.py
│   │   ├── CHANGELOG.md
│   │   ├── DEVELOPMENT.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   └── wind_farm_example.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_server.py
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_server.py
│   │   │   ├── test_sitewise_access.py
│   │   │   ├── test_sitewise_asset_models.py
│   │   │   ├── test_sitewise_assets.py
│   │   │   ├── test_sitewise_data.py
│   │   │   ├── test_sitewise_gateways.py
│   │   │   └── test_validation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-knowledge-mcp-server
│   │   └── README.md
│   ├── aws-location-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_location_server
│   │   │       ├── __init__.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_server_integration.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-msk-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_msk_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── tools
│   │   │           ├── __init__.py
│   │   │           ├── common_functions
│   │   │           │   ├── __init__.py
│   │   │           │   ├── client_manager.py
│   │   │           │   └── common_functions.py
│   │   │           ├── logs_and_telemetry
│   │   │           │   ├── __init__.py
│   │   │           │   ├── cluster_metrics_tools.py
│   │   │           │   ├── list_customer_iam_access.py
│   │   │           │   └── metric_config.py
│   │   │           ├── mutate_cluster
│   │   │           │   ├── __init__.py
│   │   │           │   ├── batch_associate_scram_secret.py
│   │   │           │   ├── batch_disassociate_scram_secret.py
│   │   │           │   ├── create_cluster_v2.py
│   │   │           │   ├── put_cluster_policy.py
│   │   │           │   ├── reboot_broker.py
│   │   │           │   ├── update_broker_count.py
│   │   │           │   ├── update_broker_storage.py
│   │   │           │   ├── update_broker_type.py
│   │   │           │   ├── update_cluster_configuration.py
│   │   │           │   ├── update_monitoring.py
│   │   │           │   └── update_security.py
│   │   │           ├── mutate_config
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_configuration.py
│   │   │           │   ├── tag_resource.py
│   │   │           │   ├── untag_resource.py
│   │   │           │   └── update_configuration.py
│   │   │           ├── mutate_vpc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_vpc_connection.py
│   │   │           │   ├── delete_vpc_connection.py
│   │   │           │   └── reject_client_vpc_connection.py
│   │   │           ├── read_cluster
│   │   │           │   ├── __init__.py
│   │   │           │   ├── describe_cluster_operation.py
│   │   │           │   ├── describe_cluster.py
│   │   │           │   ├── get_bootstrap_brokers.py
│   │   │           │   ├── get_cluster_policy.py
│   │   │           │   ├── get_compatible_kafka_versions.py
│   │   │           │   ├── list_client_vpc_connections.py
│   │   │           │   ├── list_cluster_operations.py
│   │   │           │   ├── list_nodes.py
│   │   │           │   └── list_scram_secrets.py
│   │   │           ├── read_config
│   │   │           │   ├── __init__.py
│   │   │           │   ├── describe_configuration_revision.py
│   │   │           │   ├── describe_configuration.py
│   │   │           │   ├── list_configuration_revisions.py
│   │   │           │   └── list_tags_for_resource.py
│   │   │           ├── read_global
│   │   │           │   ├── __init__.py
│   │   │           │   ├── list_clusters.py
│   │   │           │   ├── list_configurations.py
│   │   │           │   ├── list_kafka_versions.py
│   │   │           │   └── list_vpc_connections.py
│   │   │           ├── read_vpc
│   │   │           │   ├── __init__.py
│   │   │           │   └── describe_vpc_connection.py
│   │   │           └── static_tools
│   │   │               ├── __init__.py
│   │   │               └── cluster_best_practices.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_client_manager.py
│   │   │   ├── test_cluster_metrics_tools.py
│   │   │   ├── test_common_functions.py
│   │   │   ├── test_create_cluster_v2.py
│   │   │   ├── test_create_configuration.py
│   │   │   ├── test_create_vpc_connection.py
│   │   │   ├── test_delete_vpc_connection.py
│   │   │   ├── test_describe_cluster_operation.py
│   │   │   ├── test_describe_cluster.py
│   │   │   ├── test_describe_configuration_revision.py
│   │   │   ├── test_describe_configuration.py
│   │   │   ├── test_describe_vpc_connection.py
│   │   │   ├── test_get_bootstrap_brokers.py
│   │   │   ├── test_get_cluster_policy.py
│   │   │   ├── test_get_compatible_kafka_versions.py
│   │   │   ├── test_init.py
│   │   │   ├── test_list_client_vpc_connections.py
│   │   │   ├── test_list_cluster_operations.py
│   │   │   ├── test_list_clusters.py
│   │   │   ├── test_list_configuration_revisions.py
│   │   │   ├── test_list_configurations.py
│   │   │   ├── test_list_customer_iam_access.py
│   │   │   ├── test_list_kafka_versions.py
│   │   │   ├── test_list_nodes.py
│   │   │   ├── test_list_scram_secrets.py
│   │   │   ├── test_list_tags_for_resource.py
│   │   │   ├── test_list_vpc_connections.py
│   │   │   ├── test_logs_and_telemetry.py
│   │   │   ├── test_main.py
│   │   │   ├── test_mutate_cluster_init.py
│   │   │   ├── test_mutate_cluster_success_cases.py
│   │   │   ├── test_mutate_cluster.py
│   │   │   ├── test_mutate_config_init.py
│   │   │   ├── test_mutate_vpc_init.py
│   │   │   ├── test_read_cluster_init_updated.py
│   │   │   ├── test_read_cluster_init.py
│   │   │   ├── test_read_config_init.py
│   │   │   ├── test_read_global_init.py
│   │   │   ├── test_read_vpc_init.py
│   │   │   ├── test_reject_client_vpc_connection.py
│   │   │   ├── test_server.py
│   │   │   ├── test_static_tools_init.py
│   │   │   ├── test_tag_resource.py
│   │   │   ├── test_tool_descriptions.py
│   │   │   ├── test_untag_resource.py
│   │   │   └── test_update_configuration.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-pricing-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── aws_pricing_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── cdk_analyzer.py
│   │   │       ├── consts.py
│   │   │       ├── helpers.py
│   │   │       ├── models.py
│   │   │       ├── pricing_client.py
│   │   │       ├── pricing_transformer.py
│   │   │       ├── report_generator.py
│   │   │       ├── server.py
│   │   │       ├── static
│   │   │       │   ├── __init__.py
│   │   │       │   ├── COST_REPORT_TEMPLATE.md
│   │   │       │   └── patterns
│   │   │       │       ├── __init__.py
│   │   │       │       └── BEDROCK.md
│   │   │       └── terraform_analyzer.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_cdk_analyzer.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_pricing_client.py
│   │   │   ├── test_pricing_transformer.py
│   │   │   ├── test_report_generator.py
│   │   │   ├── test_server.py
│   │   │   └── test_terraform_analyzer.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── aws-serverless-mcp-server
│   │   ├── .pre-commit.config.yaml
│   │   ├── .python-version
│   │   ├── 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
│   │   │       ├── tools
│   │   │       │   ├── common
│   │   │       │   │   └── base_tool.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
│   │   │       │   ├── 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
│   │   │           ├── 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_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_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_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_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
│   │   │       │   ├── 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_pricing_tools.py
│   │   │   │   ├── test_budget_tools.py
│   │   │   │   ├── test_compute_optimizer_tools.py
│   │   │   │   ├── test_cost_anomaly_tools_enhanced.py
│   │   │   │   ├── test_cost_anomaly_tools.py
│   │   │   │   ├── test_cost_comparison_tools.py
│   │   │   │   ├── test_cost_explorer_operations.py
│   │   │   │   ├── test_cost_explorer_tools.py
│   │   │   │   ├── test_cost_optimization_hub_helpers.py
│   │   │   │   ├── test_cost_optimization_hub_tools.py
│   │   │   │   ├── test_free_tier_usage_tools_new.py
│   │   │   │   ├── test_recommendation_details_tools.py
│   │   │   │   ├── test_ri_performance_tools.py
│   │   │   │   ├── test_sp_performance_tools.py
│   │   │   │   ├── test_storage_lens_tools.py
│   │   │   │   └── test_unified_sql_tools.py
│   │   │   └── utilities
│   │   │       ├── test_aws_service_base.py
│   │   │       └── test_sql_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── ccapi-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── ccapi_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── cloud_control_utils.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── iac_generator.py
│   │   │       ├── impl
│   │   │       │   ├── __init__.py
│   │   │       │   ├── tools
│   │   │       │   │   ├── __init__.py
│   │   │       │   │   ├── explanation.py
│   │   │       │   │   ├── infrastructure_generation.py
│   │   │       │   │   ├── resource_operations.py
│   │   │       │   │   ├── security_scanning.py
│   │   │       │   │   └── session_management.py
│   │   │       │   └── utils
│   │   │       │       ├── __init__.py
│   │   │       │       └── validation.py
│   │   │       ├── infrastructure_generator.py
│   │   │       ├── models
│   │   │       │   ├── __init__.py
│   │   │       │   └── models.py
│   │   │       ├── schema_manager.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           └── __init__.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_aws_client.py
│   │   │   ├── test_checkov_install.py
│   │   │   ├── test_cloud_control_utils.py
│   │   │   ├── test_context.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_explanation.py
│   │   │   ├── test_iac_generator.py
│   │   │   ├── test_infrastructure_generation.py
│   │   │   ├── test_infrastructure_generator.py
│   │   │   ├── test_models.py
│   │   │   ├── test_resource_operations.py
│   │   │   ├── test_schema_manager.py
│   │   │   ├── test_security_scanning.py
│   │   │   ├── test_server.py
│   │   │   ├── test_session_management.py
│   │   │   └── test_validation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cdk-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cdk_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── core
│   │   │       │   ├── __init__.py
│   │   │       │   ├── resources.py
│   │   │       │   ├── search_utils.py
│   │   │       │   ├── server.py
│   │   │       │   └── tools.py
│   │   │       ├── data
│   │   │       │   ├── __init__.py
│   │   │       │   ├── cdk_nag_parser.py
│   │   │       │   ├── construct_descriptions.py
│   │   │       │   ├── genai_cdk_loader.py
│   │   │       │   ├── lambda_layer_parser.py
│   │   │       │   ├── lambda_powertools_loader.py
│   │   │       │   ├── schema_generator.py
│   │   │       │   └── solutions_constructs_parser.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           ├── __init__.py
│   │   │           ├── CDK_GENERAL_GUIDANCE.md
│   │   │           ├── CDK_NAG_GUIDANCE.md
│   │   │           └── lambda_powertools
│   │   │               ├── bedrock.md
│   │   │               ├── cdk.md
│   │   │               ├── dependencies.md
│   │   │               ├── index.md
│   │   │               ├── insights.md
│   │   │               ├── logging.md
│   │   │               ├── metrics.md
│   │   │               └── tracing.md
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── core
│   │   │   │   ├── test_resources_enhanced.py
│   │   │   │   ├── test_resources.py
│   │   │   │   ├── test_search_utils.py
│   │   │   │   ├── test_server.py
│   │   │   │   └── test_tools.py
│   │   │   └── data
│   │   │       ├── test_cdk_nag_parser.py
│   │   │       ├── test_genai_cdk_loader.py
│   │   │       ├── test_lambda_powertools_loader.py
│   │   │       ├── test_schema_generator.py
│   │   │       └── test_solutions_constructs_parser.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cfn-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cfn_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── cloud_control_utils.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── iac_generator.py
│   │   │       ├── schema_manager.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_aws_client.py
│   │   │   ├── test_cloud_control_utils.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_iac_generator.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_schema_manager.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudtrail-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudtrail_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── tools.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_tools.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudwatch-appsignals-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudwatch_appsignals_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── audit_presentation_utils.py
│   │   │       ├── audit_utils.py
│   │   │       ├── aws_clients.py
│   │   │       ├── canary_utils.py
│   │   │       ├── server.py
│   │   │       ├── service_audit_utils.py
│   │   │       ├── service_tools.py
│   │   │       ├── sli_report_client.py
│   │   │       ├── slo_tools.py
│   │   │       ├── trace_tools.py
│   │   │       └── utils.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_audit_presentation_utils.py
│   │   │   ├── test_audit_utils.py
│   │   │   ├── test_aws_profile.py
│   │   │   ├── test_canary_utils.py
│   │   │   ├── test_initialization.py
│   │   │   ├── test_server_audit_functions.py
│   │   │   ├── test_server_audit_tools.py
│   │   │   ├── test_server.py
│   │   │   ├── test_service_audit_utils.py
│   │   │   ├── test_service_tools_operations.py
│   │   │   ├── test_sli_report_client.py
│   │   │   ├── test_slo_tools.py
│   │   │   └── test_utils.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cloudwatch-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cloudwatch_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── cloudwatch_alarms
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── cloudwatch_logs
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── cloudwatch_metrics
│   │   │       │   ├── data
│   │   │       │   │   └── metric_metadata.json
│   │   │       │   ├── models.py
│   │   │       │   └── tools.py
│   │   │       ├── common.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── cloudwatch_alarms
│   │   │   │   ├── test_active_alarms.py
│   │   │   │   ├── test_alarm_history_integration.py
│   │   │   │   ├── test_alarm_history.py
│   │   │   │   └── test_alarms_error_handling.py
│   │   │   ├── cloudwatch_logs
│   │   │   │   ├── test_logs_error_handling.py
│   │   │   │   ├── test_logs_models.py
│   │   │   │   └── test_logs_server.py
│   │   │   ├── cloudwatch_metrics
│   │   │   │   ├── test_metrics_error_handling.py
│   │   │   │   ├── test_metrics_models.py
│   │   │   │   ├── test_metrics_server.py
│   │   │   │   └── test_validation_error.py
│   │   │   ├── test_common_and_server.py
│   │   │   ├── test_init.py
│   │   │   └── test_main.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── code-doc-gen-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── code_doc_gen_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── doc_generator.py
│   │   │           ├── models.py
│   │   │           ├── repomix_manager.py
│   │   │           └── templates.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_doc_generator_edge_cases.py
│   │   │   ├── test_doc_generator.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_repomix_manager_scenarios.py
│   │   │   ├── test_repomix_manager.py
│   │   │   ├── test_repomix_statistics.py
│   │   │   ├── test_server_extended.py
│   │   │   ├── test_server.py
│   │   │   └── test_templates.py
│   │   └── uv.lock
│   ├── core-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── core_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       └── static
│   │   │           ├── __init__.py
│   │   │           └── PROMPT_UNDERSTANDING.md
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_response_types.py
│   │   │   ├── test_server.py
│   │   │   └── test_static.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── cost-explorer-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── cost_explorer_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── comparison_handler.py
│   │   │       ├── constants.py
│   │   │       ├── cost_usage_handler.py
│   │   │       ├── forecasting_handler.py
│   │   │       ├── helpers.py
│   │   │       ├── metadata_handler.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── utility_handler.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_comparison_handler.py
│   │   │   ├── test_cost_usage_handler.py
│   │   │   ├── test_forecasting_handler.py
│   │   │   ├── test_helpers.py
│   │   │   ├── test_metadata_handler.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_utility_handler.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── documentdb-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   └── documentdb_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── analytic_tools.py
│   │   │       ├── config.py
│   │   │       ├── connection_tools.py
│   │   │       ├── db_management_tools.py
│   │   │       ├── query_tools.py
│   │   │       ├── server.py
│   │   │       └── write_tools.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_analytic_tools.py
│   │   │   ├── test_connection_tools.py
│   │   │   ├── test_db_management_tools.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   ├── test_query_tools.py
│   │   │   └── test_write_tools.py
│   │   └── uv.lock
│   ├── dynamodb-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── dynamodb_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common.py
│   │   │       ├── database_analysis_queries.py
│   │   │       ├── database_analyzers.py
│   │   │       ├── prompts
│   │   │       │   └── dynamodb_architect.md
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── evals
│   │   │   │   ├── dynamic_evaluators.py
│   │   │   │   ├── evaluation_registry.py
│   │   │   │   ├── logging_config.py
│   │   │   │   ├── multiturn_evaluator.py
│   │   │   │   ├── README.md
│   │   │   │   ├── scenarios.py
│   │   │   │   └── test_dspy_evals.py
│   │   │   ├── test_dynamodb_server.py
│   │   │   └── test_source_db_integration.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── ecs-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── ecs_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── api
│   │   │       │   ├── __init__.py
│   │   │       │   ├── containerize.py
│   │   │       │   ├── delete.py
│   │   │       │   ├── ecs_troubleshooting.py
│   │   │       │   ├── infrastructure.py
│   │   │       │   ├── resource_management.py
│   │   │       │   ├── status.py
│   │   │       │   └── troubleshooting_tools
│   │   │       │       ├── __init__.py
│   │   │       │       ├── detect_image_pull_failures.py
│   │   │       │       ├── fetch_cloudformation_status.py
│   │   │       │       ├── fetch_network_configuration.py
│   │   │       │       ├── fetch_service_events.py
│   │   │       │       ├── fetch_task_failures.py
│   │   │       │       ├── fetch_task_logs.py
│   │   │       │       ├── get_ecs_troubleshooting_guidance.py
│   │   │       │       └── utils.py
│   │   │       ├── main.py
│   │   │       ├── modules
│   │   │       │   ├── __init__.py
│   │   │       │   ├── aws_knowledge_proxy.py
│   │   │       │   ├── containerize.py
│   │   │       │   ├── delete.py
│   │   │       │   ├── deployment_status.py
│   │   │       │   ├── infrastructure.py
│   │   │       │   ├── resource_management.py
│   │   │       │   └── troubleshooting.py
│   │   │       ├── templates
│   │   │       │   ├── ecr_infrastructure.json
│   │   │       │   └── ecs_infrastructure.json
│   │   │       └── utils
│   │   │           ├── arn_parser.py
│   │   │           ├── aws.py
│   │   │           ├── config.py
│   │   │           ├── docker.py
│   │   │           ├── security.py
│   │   │           ├── templates.py
│   │   │           └── time_utils.py
│   │   ├── DEVELOPMENT.md
│   │   ├── pyproject.toml
│   │   ├── pyrightconfig.json
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── integ
│   │   │   │   └── mcp-inspector
│   │   │   │       ├── .gitignore
│   │   │   │       ├── README.md
│   │   │   │       ├── run-tests.sh
│   │   │   │       └── scenarios
│   │   │   │           ├── 01_comprehensive_troubleshooting
│   │   │   │           │   ├── 01_create.sh
│   │   │   │           │   ├── 02_validate.sh
│   │   │   │           │   ├── 03_cleanup.sh
│   │   │   │           │   ├── description.txt
│   │   │   │           │   └── utils
│   │   │   │           │       ├── mcp_helpers.sh
│   │   │   │           │       └── validation_helpers.sh
│   │   │   │           └── 02_test_knowledge_proxy_tools
│   │   │   │               ├── 01_create.sh
│   │   │   │               ├── 02_validate.sh
│   │   │   │               ├── 03_cleanup.sh
│   │   │   │               ├── description.txt
│   │   │   │               └── utils
│   │   │   │                   ├── knowledge_validation_helpers.sh
│   │   │   │                   └── mcp_knowledge_helpers.sh
│   │   │   ├── llm_testing
│   │   │   │   ├── invalid_cfn_template.yaml
│   │   │   │   ├── README.md
│   │   │   │   ├── run_tests.sh
│   │   │   │   ├── scenarios
│   │   │   │   │   ├── 01_cloudformation_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 02_service_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 03_task_exit_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 04_evaluation.md
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 04_network_configuration_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   ├── 05_resource_constraint_failure
│   │   │   │   │   │   ├── 01_create.sh
│   │   │   │   │   │   ├── 02_validate.sh
│   │   │   │   │   │   ├── 03_prompts.txt
│   │   │   │   │   │   ├── 05_cleanup.sh
│   │   │   │   │   │   └── description.txt
│   │   │   │   │   └── 06_load_balancer_failure
│   │   │   │   │       ├── 01_create.sh
│   │   │   │   │       ├── 02_validate.sh
│   │   │   │   │       ├── 03_prompts.txt
│   │   │   │   │       ├── 05_cleanup.sh
│   │   │   │   │       └── description.txt
│   │   │   │   ├── SCRIPT_IMPROVEMENTS.md
│   │   │   │   └── utils
│   │   │   │       ├── aws_helpers.sh
│   │   │   │       └── evaluation_template.md
│   │   │   └── unit
│   │   │       ├── __init__.py
│   │   │       ├── api
│   │   │       │   ├── conftest.py
│   │   │       │   ├── test_delete_api.py
│   │   │       │   ├── test_ecs_troubleshooting.py
│   │   │       │   ├── test_resource_management_api.py
│   │   │       │   └── troubleshooting_tools
│   │   │       │       └── test_fetch_network_configuration.py
│   │   │       ├── conftest.py
│   │   │       ├── modules
│   │   │       │   ├── test_aws_knowledge_proxy.py
│   │   │       │   └── test_resource_management_module.py
│   │   │       ├── test_aws_role_utils.py
│   │   │       ├── test_aws_utils.py
│   │   │       ├── test_containerize.py
│   │   │       ├── test_delete.py
│   │   │       ├── test_docker_utils.py
│   │   │       ├── test_docker_with_role.py
│   │   │       ├── test_image_pull_failure_extended.py
│   │   │       ├── test_image_pull_failure.py
│   │   │       ├── test_infrastructure_role.py
│   │   │       ├── test_infrastructure.py
│   │   │       ├── test_integration.py
│   │   │       ├── test_main.py
│   │   │       ├── test_resource_management_api_operation.py
│   │   │       ├── test_resource_management_tool.py
│   │   │       ├── test_resource_management.py
│   │   │       ├── test_security_integration.py
│   │   │       ├── test_status_pytest.py
│   │   │       ├── test_status.py
│   │   │       ├── troubleshooting_tools
│   │   │       │   ├── __init__.py
│   │   │       │   ├── conftest.py
│   │   │       │   ├── test_detect_image_pull_failures.py
│   │   │       │   ├── test_fetch_cloudformation_status.py
│   │   │       │   ├── test_fetch_service_events.py
│   │   │       │   ├── test_fetch_task_failures.py
│   │   │       │   ├── test_fetch_task_logs.py
│   │   │       │   ├── test_get_ecs_troubleshooting_guidance.py
│   │   │       │   ├── test_is_ecr_image_security.py
│   │   │       │   └── test_utils.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── async_test_utils.py
│   │   │           ├── test_arn_parser.py
│   │   │           ├── test_config.py
│   │   │           ├── test_docker.py
│   │   │           ├── test_response_sanitization.py
│   │   │           ├── test_security_extended.py
│   │   │           ├── test_security.py
│   │   │           ├── test_templates.py
│   │   │           └── test_time_utils.py
│   │   └── uv.lock
│   ├── eks-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── eks_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_helper.py
│   │   │       ├── cloudwatch_handler.py
│   │   │       ├── cloudwatch_metrics_guidance_handler.py
│   │   │       ├── consts.py
│   │   │       ├── data
│   │   │       │   └── eks_cloudwatch_metrics_guidance.json
│   │   │       ├── eks_kb_handler.py
│   │   │       ├── eks_stack_handler.py
│   │   │       ├── iam_handler.py
│   │   │       ├── insights_handler.py
│   │   │       ├── k8s_apis.py
│   │   │       ├── k8s_client_cache.py
│   │   │       ├── k8s_handler.py
│   │   │       ├── logging_helper.py
│   │   │       ├── models.py
│   │   │       ├── scripts
│   │   │       │   └── update_eks_cloudwatch_metrics_guidance.py
│   │   │       ├── server.py
│   │   │       ├── templates
│   │   │       │   ├── eks-templates
│   │   │       │   │   └── eks-with-vpc.yaml
│   │   │       │   └── k8s-templates
│   │   │       │       ├── deployment.yaml
│   │   │       │       └── service.yaml
│   │   │       └── vpc_config_handler.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_aws_helper.py
│   │   │   ├── test_cloudwatch_handler.py
│   │   │   ├── test_cloudwatch_metrics_guidance_handler.py
│   │   │   ├── test_eks_kb_handler.py
│   │   │   ├── test_eks_stack_handler.py
│   │   │   ├── test_iam_handler.py
│   │   │   ├── test_init.py
│   │   │   ├── test_insights_handler.py
│   │   │   ├── test_k8s_apis.py
│   │   │   ├── test_k8s_client_cache.py
│   │   │   ├── test_k8s_handler.py
│   │   │   ├── test_logging_helper.py
│   │   │   ├── test_main.py
│   │   │   ├── test_models.py
│   │   │   ├── test_server.py
│   │   │   └── test_vpc_config_handler.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── elasticache-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── elasticache_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common
│   │   │       │   ├── __init__.py
│   │   │       │   ├── connection.py
│   │   │       │   ├── decorators.py
│   │   │       │   └── server.py
│   │   │       ├── context.py
│   │   │       ├── main.py
│   │   │       └── tools
│   │   │           ├── __init__.py
│   │   │           ├── cc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── connect.py
│   │   │           │   ├── create.py
│   │   │           │   ├── delete.py
│   │   │           │   ├── describe.py
│   │   │           │   ├── modify.py
│   │   │           │   ├── parsers.py
│   │   │           │   └── processors.py
│   │   │           ├── ce
│   │   │           │   ├── __init__.py
│   │   │           │   └── get_cost_and_usage.py
│   │   │           ├── cw
│   │   │           │   ├── __init__.py
│   │   │           │   └── get_metric_statistics.py
│   │   │           ├── cwlogs
│   │   │           │   ├── __init__.py
│   │   │           │   ├── create_log_group.py
│   │   │           │   ├── describe_log_groups.py
│   │   │           │   ├── describe_log_streams.py
│   │   │           │   ├── filter_log_events.py
│   │   │           │   └── get_log_events.py
│   │   │           ├── firehose
│   │   │           │   ├── __init__.py
│   │   │           │   └── list_delivery_streams.py
│   │   │           ├── misc
│   │   │           │   ├── __init__.py
│   │   │           │   ├── batch_apply_update_action.py
│   │   │           │   ├── batch_stop_update_action.py
│   │   │           │   ├── describe_cache_engine_versions.py
│   │   │           │   ├── describe_engine_default_parameters.py
│   │   │           │   ├── describe_events.py
│   │   │           │   └── describe_service_updates.py
│   │   │           ├── rg
│   │   │           │   ├── __init__.py
│   │   │           │   ├── complete_migration.py
│   │   │           │   ├── connect.py
│   │   │           │   ├── create.py
│   │   │           │   ├── delete.py
│   │   │           │   ├── describe.py
│   │   │           │   ├── modify.py
│   │   │           │   ├── parsers.py
│   │   │           │   ├── processors.py
│   │   │           │   ├── start_migration.py
│   │   │           │   └── test_migration.py
│   │   │           └── serverless
│   │   │               ├── __init__.py
│   │   │               ├── connect.py
│   │   │               ├── create.py
│   │   │               ├── delete.py
│   │   │               ├── describe.py
│   │   │               ├── models.py
│   │   │               └── modify.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_connection.py
│   │   │   ├── test_decorators.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── tools
│   │   │       ├── cc
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_connect_additional.py
│   │   │       │   ├── test_connect_coverage_additional.py
│   │   │       │   ├── test_connect_coverage.py
│   │   │       │   ├── test_connect.py
│   │   │       │   ├── test_create_additional.py
│   │   │       │   ├── test_create.py
│   │   │       │   ├── test_delete.py
│   │   │       │   ├── test_describe.py
│   │   │       │   ├── test_modify.py
│   │   │       │   ├── test_parsers.py
│   │   │       │   └── test_processors.py
│   │   │       ├── ce
│   │   │       │   ├── __init__.py
│   │   │       │   └── test_get_cost_and_usage.py
│   │   │       ├── cw
│   │   │       │   └── test_get_metric_statistics.py
│   │   │       ├── cwlogs
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_create_log_group.py
│   │   │       │   ├── test_describe_log_groups.py
│   │   │       │   ├── test_describe_log_streams.py
│   │   │       │   ├── test_filter_log_events.py
│   │   │       │   └── test_get_log_events.py
│   │   │       ├── firehose
│   │   │       │   └── test_list_delivery_streams.py
│   │   │       ├── misc
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_batch_apply_update_action.py
│   │   │       │   ├── test_batch_stop_update_action.py
│   │   │       │   ├── test_describe_cache_engine_versions.py
│   │   │       │   ├── test_describe_engine_default_parameters.py
│   │   │       │   ├── test_describe_events.py
│   │   │       │   └── test_describe_service_updates.py
│   │   │       ├── rg
│   │   │       │   ├── __init__.py
│   │   │       │   ├── test_complete_migration.py
│   │   │       │   ├── test_connect_additional.py
│   │   │       │   ├── test_connect_coverage_additional.py
│   │   │       │   ├── test_connect_optional_fields.py
│   │   │       │   ├── test_connect_partial_coverage.py
│   │   │       │   ├── test_connect.py
│   │   │       │   ├── test_create.py
│   │   │       │   ├── test_delete.py
│   │   │       │   ├── test_describe.py
│   │   │       │   ├── test_modify.py
│   │   │       │   ├── test_parsers.py
│   │   │       │   ├── test_processors.py
│   │   │       │   ├── test_start_migration.py
│   │   │       │   └── test_test_migration.py
│   │   │       └── serverless
│   │   │           ├── test_connect_additional.py
│   │   │           ├── test_connect_coverage_additional.py
│   │   │           ├── test_connect_optional_fields.py
│   │   │           ├── test_connect.py
│   │   │           ├── test_create.py
│   │   │           ├── test_delete.py
│   │   │           ├── test_describe.py
│   │   │           └── test_modify.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── finch-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── finch_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── consts.py
│   │   │       ├── models.py
│   │   │       ├── server.py
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           ├── build.py
│   │   │           ├── common.py
│   │   │           ├── ecr.py
│   │   │           ├── push.py
│   │   │           └── vm.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── test_cli_flags.py
│   │   │   ├── test_logging_configuration.py
│   │   │   ├── test_server.py
│   │   │   ├── test_utils_build.py
│   │   │   ├── test_utils_common.py
│   │   │   ├── test_utils_ecr.py
│   │   │   ├── test_utils_push.py
│   │   │   └── test_utils_vm.py
│   │   └── uv.lock
│   ├── frontend-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── frontend_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── server.py
│   │   │       ├── static
│   │   │       │   └── react
│   │   │       │       ├── essential-knowledge.md
│   │   │       │       └── troubleshooting.md
│   │   │       └── utils
│   │   │           ├── __init__.py
│   │   │           └── file_utils.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_file_utils.py
│   │   │   ├── test_init.py
│   │   │   ├── test_main.py
│   │   │   └── test_server.py
│   │   └── uv.lock
│   ├── git-repo-research-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── git_repo_research_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── defaults.py
│   │   │       ├── embeddings.py
│   │   │       ├── github_search.py
│   │   │       ├── indexer.py
│   │   │       ├── models.py
│   │   │       ├── repository.py
│   │   │       ├── search.py
│   │   │       ├── server.py
│   │   │       └── utils.py
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_errors_repository.py
│   │   │   ├── test_github_search_edge_cases.py
│   │   │   ├── test_graphql_github_search.py
│   │   │   ├── test_local_repository.py
│   │   │   ├── test_repository_utils.py
│   │   │   ├── test_rest_github_search.py
│   │   │   ├── test_search.py
│   │   │   ├── test_server.py
│   │   │   └── test_url_repository.py
│   │   └── uv.lock
│   ├── healthlake-mcp-server
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── healthlake_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── fhir_operations.py
│   │   │       ├── main.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── CONTRIBUTING.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── mcp_config.json
│   │   │   └── README.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.py
│   │   │   ├── test_fhir_client_comprehensive.py
│   │   │   ├── test_fhir_error_scenarios.py
│   │   │   ├── test_fhir_operations.py
│   │   │   ├── test_integration_mock_based.py
│   │   │   ├── test_main_edge_cases.py
│   │   │   ├── test_main.py
│   │   │   ├── test_mcp_integration_coverage.py
│   │   │   ├── test_models_edge_cases.py
│   │   │   ├── test_models.py
│   │   │   ├── test_readonly_mode.py
│   │   │   ├── test_server_core.py
│   │   │   ├── test_server_error_handling.py
│   │   │   ├── test_server_mcp_handlers.py
│   │   │   ├── test_server_toolhandler.py
│   │   │   └── test_server_validation.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── iam-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── iam_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── aws_client.py
│   │   │       ├── context.py
│   │   │       ├── errors.py
│   │   │       ├── models.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── DESIGN_COMPLIANCE.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── get_policy_document_example.py
│   │   │   └── inline_policy_demo.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── run_tests.sh
│   │   ├── tests
│   │   │   ├── test_context.py
│   │   │   ├── test_errors.py
│   │   │   ├── test_inline_policies.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── lambda-tool-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── lambda_tool_mcp_server
│   │   │       ├── __init__.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── examples
│   │   │   ├── README.md
│   │   │   └── sample_functions
│   │   │       ├── customer-create
│   │   │       │   └── app.py
│   │   │       ├── customer-id-from-email
│   │   │       │   └── app.py
│   │   │       ├── customer-info-from-id
│   │   │       │   └── app.py
│   │   │       └── template.yml
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── __init__.py
│   │   │   ├── .gitignore
│   │   │   ├── conftest.py
│   │   │   ├── README.md
│   │   │   ├── test_format_lambda_response.py
│   │   │   ├── test_integration_coverage.py
│   │   │   ├── test_integration.py
│   │   │   ├── test_register_lambda_functions.py
│   │   │   ├── test_schema_integration.py
│   │   │   ├── test_server_coverage_additional.py
│   │   │   ├── test_server_coverage.py
│   │   │   └── test_server.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── mcp-lambda-handler
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   └── mcp_lambda_handler
│   │   │       ├── __init__.py
│   │   │       ├── mcp_lambda_handler.py
│   │   │       ├── session.py
│   │   │       └── types.py
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   └── test_lambda_handler.py
│   │   └── uv.lock
│   ├── memcached-mcp-server
│   │   ├── .gitignore
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── memcached_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── common
│   │   │       │   ├── config.py
│   │   │       │   ├── connection.py
│   │   │       │   └── server.py
│   │   │       ├── context.py
│   │   │       ├── main.py
│   │   │       └── tools
│   │   │           └── cache.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── ELASTICACHECONNECT.md
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── test_cache_readonly.py
│   │   │   ├── test_cache.py
│   │   │   ├── test_connection.py
│   │   │   ├── test_init.py
│   │   │   └── test_main.py
│   │   ├── uv-requirements.txt
│   │   └── uv.lock
│   ├── mysql-mcp-server
│   │   ├── .python-version
│   │   ├── awslabs
│   │   │   ├── __init__.py
│   │   │   └── mysql_mcp_server
│   │   │       ├── __init__.py
│   │   │       ├── mutable_sql_detector.py
│   │   │       └── server.py
│   │   ├── CHANGELOG.md
│   │   ├── docker-healthcheck.sh
│   │   ├── Dockerfile
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── tests
│   │   │   ├── conftest.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/cloudwatch-appsignals-mcp-server/tests/test_server.py:
--------------------------------------------------------------------------------

```python
"""Tests for CloudWatch Application Signals MCP Server."""

import json
import pytest
from awslabs.cloudwatch_appsignals_mcp_server.server import _filter_operation_targets, main
from awslabs.cloudwatch_appsignals_mcp_server.service_tools import (
    get_service_detail,
    list_monitored_services,
    query_service_metrics,
)
from awslabs.cloudwatch_appsignals_mcp_server.slo_tools import get_slo
from awslabs.cloudwatch_appsignals_mcp_server.trace_tools import (
    check_transaction_search_enabled,
    get_trace_summaries_paginated,
    list_slis,
    query_sampled_traces,
    search_transaction_spans,
)
from awslabs.cloudwatch_appsignals_mcp_server.utils import remove_null_values
from botocore.exceptions import ClientError
from datetime import datetime, timedelta, timezone
from unittest.mock import AsyncMock, MagicMock, patch


@pytest.fixture(autouse=True)
def mock_aws_clients():
    """Mock all AWS clients to prevent real API calls during tests."""
    # Create mock clients
    mock_logs_client = MagicMock()
    mock_appsignals_client = MagicMock()
    mock_cloudwatch_client = MagicMock()
    mock_xray_client = MagicMock()
    mock_synthetics_client = MagicMock()
    mock_s3_client = MagicMock()

    # Patch the clients in all modules where they're imported
    patches = [
        # Original aws_clients module
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.aws_clients.logs_client', mock_logs_client
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.aws_clients.appsignals_client',
            mock_appsignals_client,
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.aws_clients.cloudwatch_client',
            mock_cloudwatch_client,
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.aws_clients.xray_client', mock_xray_client
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.aws_clients.synthetics_client',
            mock_synthetics_client,
        ),
        patch('awslabs.cloudwatch_appsignals_mcp_server.aws_clients.s3_client', mock_s3_client),
        # Service tools module (check what's actually imported)
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.service_tools.appsignals_client',
            mock_appsignals_client,
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.service_tools.cloudwatch_client',
            mock_cloudwatch_client,
        ),
        # SLO tools module (check what's actually imported)
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.slo_tools.appsignals_client',
            mock_appsignals_client,
        ),
        # Trace tools module (logs_client, xray_client, and appsignals_client are imported)
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.logs_client', mock_logs_client
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.xray_client', mock_xray_client
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.appsignals_client',
            mock_appsignals_client,
        ),
        # SLI report client module (appsignals_client and cloudwatch_client are imported)
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.sli_report_client.appsignals_client',
            mock_appsignals_client,
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.sli_report_client.cloudwatch_client',
            mock_cloudwatch_client,
        ),
        patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.synthetics_client',
            mock_synthetics_client,
        ),
        patch('awslabs.cloudwatch_appsignals_mcp_server.server.s3_client', mock_s3_client),
        patch('awslabs.cloudwatch_appsignals_mcp_server.server.iam_client', MagicMock()),
    ]

    # Start all patches
    for p in patches:
        p.start()

    try:
        yield {
            'logs_client': mock_logs_client,
            'appsignals_client': mock_appsignals_client,
            'cloudwatch_client': mock_cloudwatch_client,
            'xray_client': mock_xray_client,
            'synthetics_client': mock_synthetics_client,
            's3_client': mock_s3_client,
        }
    finally:
        # Stop all patches
        for p in patches:
            p.stop()


@pytest.fixture
def mock_mcp():
    """Mock the FastMCP instance."""
    with patch('awslabs.cloudwatch_appsignals_mcp_server.server.mcp') as mock:
        yield mock


@pytest.mark.asyncio
async def test_list_monitored_services_success(mock_aws_clients):
    """Test successful listing of monitored services."""
    mock_response = {
        'ServiceSummaries': [
            {
                'KeyAttributes': {
                    'Name': 'test-service',
                    'Type': 'AWS::ECS::Service',
                    'Environment': 'production',
                }
            }
        ]
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_response

    result = await list_monitored_services()

    assert 'Application Signals Services (1 total)' in result
    assert 'test-service' in result
    assert 'AWS::ECS::Service' in result


@pytest.mark.asyncio
async def test_list_monitored_services_empty(mock_aws_clients):
    """Test when no services are found."""
    mock_response = {'ServiceSummaries': []}

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_response

    result = await list_monitored_services()

    assert result == 'No services found in Application Signals.'


@pytest.mark.asyncio
async def test_get_service_detail_success(mock_aws_clients):
    """Test successful retrieval of service details."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {
        'Service': {
            'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'},
            'AttributeMaps': [{'Platform': 'ECS', 'Application': 'test-app'}],
            'MetricReferences': [
                {
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricName': 'Latency',
                    'MetricType': 'GAUGE',
                    'Dimensions': [{'Name': 'Service', 'Value': 'test-service'}],
                }
            ],
            'LogGroupReferences': [{'Identifier': '/aws/ecs/test-service'}],
        }
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response

    result = await get_service_detail('test-service')

    assert 'Service Details: test-service' in result
    assert 'AWS::ECS::Service' in result
    assert 'Platform: ECS' in result
    assert 'AWS/ApplicationSignals/Latency' in result
    assert '/aws/ecs/test-service' in result


@pytest.mark.asyncio
async def test_get_service_detail_not_found(mock_aws_clients):
    """Test when service is not found."""
    mock_response = {'ServiceSummaries': []}

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_response

    result = await get_service_detail('nonexistent-service')

    assert "Service 'nonexistent-service' not found" in result


@pytest.mark.asyncio
async def test_query_service_metrics_success(mock_aws_clients):
    """Test successful query of service metrics."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {
        'Service': {
            'MetricReferences': [
                {
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricName': 'Latency',
                    'Dimensions': [{'Name': 'Service', 'Value': 'test-service'}],
                }
            ]
        }
    }

    mock_metric_response = {
        'Datapoints': [
            {
                'Timestamp': datetime.now(timezone.utc),
                'Average': 100.5,
                'p99': 150.2,
                'Unit': 'Milliseconds',
            }
        ]
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response
    mock_aws_clients['cloudwatch_client'].get_metric_statistics.return_value = mock_metric_response

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert 'Metrics for test-service - Latency' in result
    assert 'Average Statistics:' in result
    assert 'p99 Statistics:' in result


@pytest.mark.asyncio
async def test_query_service_metrics_list_available(mock_aws_clients):
    """Test listing available metrics when no specific metric is requested."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {
        'Service': {
            'MetricReferences': [
                {
                    'MetricName': 'Latency',
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricType': 'GAUGE',
                },
                {
                    'MetricName': 'Error',
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricType': 'COUNT',
                },
            ]
        }
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='',  # Empty to list available metrics
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert "Available metrics for service 'test-service'" in result
    assert 'Latency' in result
    assert 'Error' in result


@pytest.mark.asyncio
async def test_get_slo_success(mock_aws_clients):
    """Test successful retrieval of SLO details."""
    mock_slo_response = {
        'Slo': {
            'Name': 'test-slo',
            'Arn': 'arn:aws:application-signals:us-east-1:123456789012:slo/test-slo',
            'Description': 'Test SLO for latency',
            'EvaluationType': 'REQUEST_BASED',
            'CreatedTime': '2024-01-01T00:00:00Z',
            'LastUpdatedTime': '2024-01-02T00:00:00Z',
            'Goal': {
                'AttainmentGoal': 99.9,
                'WarningThreshold': 99.0,
                'Interval': {'RollingInterval': {'Duration': 7, 'DurationUnit': 'DAYS'}},
            },
            'RequestBasedSli': {
                'RequestBasedSliMetric': {
                    'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'},
                    'OperationName': 'GET /api/test',
                    'MetricType': 'LATENCY',
                    'MetricDataQueries': [
                        {
                            'Id': 'query1',
                            'MetricStat': {
                                'Metric': {
                                    'Namespace': 'AWS/ApplicationSignals',
                                    'MetricName': 'Latency',
                                    'Dimensions': [{'Name': 'Service', 'Value': 'test-service'}],
                                },
                                'Period': 60,
                                'Stat': 'Average',
                            },
                        }
                    ],
                },
                'MetricThreshold': 1000,
                'ComparisonOperator': 'GreaterThan',
            },
        }
    }

    mock_aws_clients[
        'appsignals_client'
    ].get_service_level_objective.return_value = mock_slo_response

    result = await get_slo('test-slo-id')

    assert 'Service Level Objective Details' in result
    assert 'test-slo' in result
    assert 'REQUEST_BASED' in result
    assert '99.9%' in result
    assert 'GET /api/test' in result
    assert 'annotation[aws.local.operation]="GET /api/test"' in result


@pytest.mark.asyncio
async def test_get_slo_not_found(mock_aws_clients):
    """Test when SLO is not found."""
    mock_aws_clients['appsignals_client'].get_service_level_objective.return_value = {'Slo': None}

    result = await get_slo('nonexistent-slo')

    assert 'No SLO found with ID: nonexistent-slo' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_success(mock_aws_clients):
    """Test successful transaction search."""
    mock_query_response = {
        'queryId': 'test-query-id',
        'status': 'Complete',
        'statistics': {'recordsMatched': 10},
        'results': [
            [
                {'field': 'spanId', 'value': 'span1'},
                {'field': 'timestamp', 'value': '2024-01-01T00:00:00Z'},
            ]
        ],
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.return_value = {'queryId': 'test-query-id'}
        mock_aws_clients['logs_client'].get_query_results.return_value = mock_query_response

        result = await search_transaction_spans(
            log_group_name='aws/spans',
            start_time='2024-01-01T00:00:00+00:00',  # Fixed ISO format
            end_time='2024-01-01T01:00:00+00:00',
            query_string='fields @timestamp, spanId',
            limit=100,
            max_timeout=30,
        )

        assert result['status'] == 'Complete'
        assert result['queryId'] == 'test-query-id'
        assert len(result['results']) == 1
        assert result['results'][0]['spanId'] == 'span1'


@pytest.mark.asyncio
async def test_search_transaction_spans_not_enabled(mock_aws_clients):
    """Test when transaction search is not enabled."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (False, 'XRay', 'INACTIVE')

        result = await search_transaction_spans(
            log_group_name='',
            start_time='2024-01-01T00:00:00+00:00',
            end_time='2024-01-01T01:00:00+00:00',
            query_string='fields @timestamp',
            limit=None,
            max_timeout=30,
        )

        assert result['status'] == 'Transaction Search Not Available'
        assert not result['transaction_search_status']['enabled']


@pytest.mark.asyncio
async def test_list_slis_success(mock_aws_clients):
    """Test successful listing of SLI status."""
    mock_services_response = {
        'ServiceSummaries': [
            {
                'KeyAttributes': {
                    'Name': 'test-service',
                    'Type': 'AWS::ECS::Service',
                    'Environment': 'production',
                }
            }
        ]
    }

    # Mock boto3.client calls in SLIReportClient
    with patch('boto3.client') as mock_boto3_client:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
        ) as mock_check:
            # Configure boto3.client to return our mocked clients
            def boto3_client_side_effect(service_name, **kwargs):
                if service_name == 'application-signals':
                    return mock_aws_clients['appsignals_client']
                elif service_name == 'cloudwatch':
                    return mock_aws_clients['cloudwatch_client']
                else:
                    return MagicMock()

            mock_boto3_client.side_effect = boto3_client_side_effect

            mock_aws_clients[
                'appsignals_client'
            ].list_services.return_value = mock_services_response
            mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')

            # Mock SLO summaries response for SLIReportClient
            mock_slo_response = {
                'SloSummaries': [
                    {
                        'Name': 'test-slo',
                        'Arn': 'arn:aws:application-signals:us-east-1:123456789012:slo/test-slo',
                        'KeyAttributes': {'Name': 'test-service'},
                        'OperationName': 'GET /api',
                        'CreatedTime': datetime.now(timezone.utc),
                    }
                ]
            }
            mock_aws_clients[
                'appsignals_client'
            ].list_service_level_objectives.return_value = mock_slo_response

            # Mock metric data response showing breach
            mock_metric_response = {
                'MetricDataResults': [
                    {
                        'Id': 'slo0',
                        'Timestamps': [datetime.now(timezone.utc)],
                        'Values': [1.0],  # Breach count > 0 indicates breach
                    }
                ]
            }
            mock_aws_clients[
                'cloudwatch_client'
            ].get_metric_data.return_value = mock_metric_response

            result = await list_slis(hours=24)

            assert 'SLI Status Report - Last 24 hours' in result
            assert 'Transaction Search: ENABLED' in result
            assert 'BREACHED SERVICES:' in result
            assert 'test-service' in result


@pytest.mark.asyncio
async def test_query_sampled_traces_success(mock_aws_clients):
    """Test successful query of sampled traces."""
    mock_traces = [
        {
            'Id': 'trace1',
            'Duration': 0.5,
            'ResponseTime': 500,
            'HasError': False,
            'HasFault': True,
            'HasThrottle': False,
            'Http': {'HttpStatus': 500},
            'FaultRootCauses': [
                {
                    'Services': [
                        {
                            'Name': 'test-service',
                            'Exceptions': [{'Message': 'Internal server error'}],
                        }
                    ]
                }
            ],
        }
    ]

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_get_traces:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
        ) as mock_check:
            mock_get_traces.return_value = mock_traces
            mock_check.return_value = (False, 'XRay', 'INACTIVE')

            result_json = await query_sampled_traces(
                start_time='2024-01-01T00:00:00Z',
                end_time='2024-01-01T01:00:00Z',
                filter_expression='service("test-service"){fault = true}',
            )

            result = json.loads(result_json)
            assert result['TraceCount'] == 1
            assert result['TraceSummaries'][0]['Id'] == 'trace1'
            assert result['TraceSummaries'][0]['HasFault'] is True


@pytest.mark.asyncio
async def test_query_sampled_traces_time_window_too_large(mock_aws_clients):
    """Test when time window is too large."""
    result_json = await query_sampled_traces(
        start_time='2024-01-01T00:00:00Z',
        end_time='2024-01-02T00:00:00Z',  # 24 hours > 6 hours max
        filter_expression='service("test-service")',
    )

    result = json.loads(result_json)
    assert 'error' in result
    assert 'Time window too large' in result['error']


def test_get_trace_summaries_paginated():
    """Test paginated trace retrieval."""
    mock_client = MagicMock()
    mock_responses = [
        {'TraceSummaries': [{'Id': 'trace1'}, {'Id': 'trace2'}], 'NextToken': 'token1'},
        {'TraceSummaries': [{'Id': 'trace3'}]},
    ]
    mock_client.get_trace_summaries.side_effect = mock_responses

    start_time = datetime.now(timezone.utc) - timedelta(hours=1)
    end_time = datetime.now(timezone.utc)

    traces = get_trace_summaries_paginated(
        mock_client, start_time, end_time, 'service("test")', max_traces=10
    )

    assert len(traces) == 3
    assert traces[0]['Id'] == 'trace1'
    assert traces[2]['Id'] == 'trace3'


def test_get_trace_summaries_paginated_with_error():
    """Test paginated trace retrieval with error."""
    mock_client = MagicMock()
    mock_client.get_trace_summaries.side_effect = Exception('API Error')

    start_time = datetime.now(timezone.utc) - timedelta(hours=1)
    end_time = datetime.now(timezone.utc)

    traces = get_trace_summaries_paginated(
        mock_client, start_time, end_time, 'service("test")', max_traces=10
    )

    assert len(traces) == 0  # Should return empty list on error


def test_check_transaction_search_enabled(mock_aws_clients):
    """Test checking transaction search status."""
    mock_aws_clients['xray_client'].get_trace_segment_destination.return_value = {
        'Destination': 'CloudWatchLogs',
        'Status': 'ACTIVE',
    }

    is_enabled, destination, status = check_transaction_search_enabled()

    assert is_enabled is True
    assert destination == 'CloudWatchLogs'
    assert status == 'ACTIVE'


def test_check_transaction_search_enabled_not_active(mock_aws_clients):
    """Test checking transaction search when not active."""
    mock_aws_clients['xray_client'].get_trace_segment_destination.return_value = {
        'Destination': 'XRay',
        'Status': 'INACTIVE',
    }

    is_enabled, destination, status = check_transaction_search_enabled()

    assert is_enabled is False
    assert destination == 'XRay'
    assert status == 'INACTIVE'


def test_check_transaction_search_enabled_error(mock_aws_clients):
    """Test checking transaction search with error."""
    mock_aws_clients['xray_client'].get_trace_segment_destination.side_effect = Exception(
        'API Error'
    )

    is_enabled, destination, status = check_transaction_search_enabled()

    assert is_enabled is False
    assert destination == 'Unknown'
    assert status == 'Error'


def test_remove_null_values():
    """Test remove_null_values function."""
    # Test with mix of None and non-None values
    input_dict = {
        'key1': 'value1',
        'key2': None,
        'key3': 'value3',
        'key4': None,
        'key5': 0,  # Should not be removed
        'key6': '',  # Should not be removed
        'key7': False,  # Should not be removed
    }

    result = remove_null_values(input_dict)

    assert result == {
        'key1': 'value1',
        'key3': 'value3',
        'key5': 0,
        'key6': '',
        'key7': False,
    }
    assert 'key2' not in result
    assert 'key4' not in result


@pytest.mark.asyncio
async def test_list_monitored_services_client_error(mock_aws_clients):
    """Test ClientError handling in list_monitored_services."""
    mock_aws_clients['appsignals_client'].list_services.side_effect = ClientError(
        error_response={
            'Error': {
                'Code': 'AccessDeniedException',
                'Message': 'User is not authorized to perform this action',
            }
        },
        operation_name='ListServices',
    )

    result = await list_monitored_services()

    assert 'AWS Error: User is not authorized to perform this action' in result


@pytest.mark.asyncio
async def test_list_monitored_services_general_exception(mock_aws_clients):
    """Test general exception handling in list_monitored_services."""
    mock_aws_clients['appsignals_client'].list_services.side_effect = Exception(
        'Unexpected error occurred'
    )

    result = await list_monitored_services()

    assert 'Error: Unexpected error occurred' in result


@pytest.mark.asyncio
async def test_get_service_detail_client_error(mock_aws_clients):
    """Test ClientError handling in get_service_detail."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.side_effect = ClientError(
        error_response={
            'Error': {
                'Code': 'ResourceNotFoundException',
                'Message': 'Service not found in Application Signals',
            }
        },
        operation_name='GetService',
    )

    result = await get_service_detail('test-service')

    assert 'AWS Error: Service not found in Application Signals' in result


@pytest.mark.asyncio
async def test_get_service_detail_general_exception(mock_aws_clients):
    """Test general exception handling in get_service_detail."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.side_effect = Exception(
        'Unexpected error in get_service'
    )

    result = await get_service_detail('test-service')

    assert 'Error: Unexpected error in get_service' in result


@pytest.mark.asyncio
async def test_query_service_metrics_no_datapoints(mock_aws_clients):
    """Test query service metrics when no datapoints are returned."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {
        'Service': {
            'MetricReferences': [
                {
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricName': 'Latency',
                    'Dimensions': [{'Name': 'Service', 'Value': 'test-service'}],
                }
            ]
        }
    }

    mock_metric_response = {'Datapoints': []}

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response
    mock_aws_clients['cloudwatch_client'].get_metric_statistics.return_value = mock_metric_response

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert 'No data points found' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_timeout(mock_aws_clients):
    """Test search transaction spans with timeout."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.trace_tools.timer') as mock_timer:
            # Mock asyncio.sleep to prevent actual waiting
            with patch('asyncio.sleep', new_callable=AsyncMock):
                mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
                mock_aws_clients['logs_client'].start_query.return_value = {
                    'queryId': 'test-query-id'
                }
                mock_aws_clients['logs_client'].get_query_results.return_value = {
                    'status': 'Running'
                }

                # Simulate timeout by making timer exceed max_timeout
                mock_timer.side_effect = [
                    0,
                    0,
                    0,
                    31,
                    31,
                ]  # start_time_perf, poll_start, poll check 1, poll check 2

                result = await search_transaction_spans(
                    log_group_name='',
                    start_time='2024-01-01T00:00:00+00:00',
                    end_time='2024-01-01T01:00:00+00:00',
                    query_string='fields @timestamp',
                    limit=None,
                    max_timeout=30,
                )

                assert result['status'] == 'Polling Timeout'
                assert 'did not complete within 30 seconds' in result['message']


def test_main_normal_execution(mock_mcp):
    """Test normal execution of main function."""
    main()
    mock_mcp.run.assert_called_once_with(transport='stdio')


def test_main_keyboard_interrupt(mock_mcp):
    """Test KeyboardInterrupt handling in main function."""
    mock_mcp.run.side_effect = KeyboardInterrupt()
    # Should not raise an exception
    main()
    mock_mcp.run.assert_called_once_with(transport='stdio')


def test_main_general_exception(mock_mcp):
    """Test general exception handling in main function."""
    mock_mcp.run.side_effect = Exception('Server error')
    with pytest.raises(Exception, match='Server error'):
        main()
    mock_mcp.run.assert_called_once_with(transport='stdio')


@pytest.mark.asyncio
async def test_get_slo_period_based(mock_aws_clients):
    """Test get_slo with period-based SLI configuration."""
    mock_slo_response = {
        'Slo': {
            'Name': 'test-slo-period',
            'Arn': 'arn:aws:application-signals:us-east-1:123456789012:slo/test-slo',
            'EvaluationType': 'PERIOD_BASED',
            'Sli': {
                'SliMetric': {
                    'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::Lambda::Function'},
                    'OperationName': 'ProcessOrder',
                    'MetricType': 'AVAILABILITY',
                    'DependencyConfig': {
                        'DependencyKeyAttributes': {'Name': 'payment-service'},
                        'DependencyOperationName': 'ProcessPayment',
                    },
                },
                'MetricThreshold': 0.99,
                'ComparisonOperator': 'LessThan',
            },
            'BurnRateConfigurations': [
                {'LookBackWindowMinutes': 5},
                {'LookBackWindowMinutes': 60},
            ],
        }
    }

    mock_aws_clients[
        'appsignals_client'
    ].get_service_level_objective.return_value = mock_slo_response

    result = await get_slo('test-slo-period')

    assert 'PERIOD_BASED' in result
    assert 'ProcessOrder' in result
    assert 'annotation[aws.remote.operation]="ProcessPayment"' in result
    assert 'Burn Rate Configurations' in result


@pytest.mark.asyncio
async def test_list_slis_with_error_in_sli_client(mock_aws_clients):
    """Test list_slis when SLIReportClient throws error for some services."""
    mock_services_response = {
        'ServiceSummaries': [
            {
                'KeyAttributes': {
                    'Name': 'test-service-1',
                    'Type': 'AWS::ECS::Service',
                    'Environment': 'production',
                }
            },
            {
                'KeyAttributes': {
                    'Name': 'test-service-2',
                    'Type': 'AWS::Lambda::Function',
                    'Environment': 'staging',
                }
            },
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.SLIReportClient'
    ) as mock_sli_client:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
        ) as mock_check:
            mock_aws_clients[
                'appsignals_client'
            ].list_services.return_value = mock_services_response
            mock_check.return_value = (False, 'XRay', 'INACTIVE')

            # First service succeeds, second fails
            mock_report = MagicMock()
            mock_report.breached_slo_count = 0
            mock_report.ok_slo_count = 3
            mock_report.total_slo_count = 3
            mock_report.sli_status = 'OK'
            mock_report.start_time = datetime.now(timezone.utc) - timedelta(hours=24)
            mock_report.end_time = datetime.now(timezone.utc)

            mock_sli_client.return_value.generate_sli_report.side_effect = [
                mock_report,
                Exception('Failed to get SLI report'),
            ]

            result = await list_slis(hours=24)

            assert 'Transaction Search: NOT ENABLED' in result
            assert 'HEALTHY SERVICES:' in result
            assert 'INSUFFICIENT DATA:' in result
            assert 'test-service-1' in result
            assert 'test-service-2' in result


@pytest.mark.asyncio
async def test_query_service_metrics_service_not_found(mock_aws_clients):
    """Test query service metrics when service is not found."""
    mock_list_response = {'ServiceSummaries': []}

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response

    result = await query_service_metrics(
        service_name='nonexistent-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert "Service 'nonexistent-service' not found" in result


@pytest.mark.asyncio
async def test_query_service_metrics_no_metrics(mock_aws_clients):
    """Test query service metrics when service has no metrics."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {'Service': {'MetricReferences': []}}

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert "No metrics found for service 'test-service'" in result


@pytest.mark.asyncio
async def test_query_service_metrics_metric_not_found(mock_aws_clients):
    """Test query service metrics when specific metric is not found."""
    mock_list_response = {
        'ServiceSummaries': [
            {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
        ]
    }

    mock_get_response = {
        'Service': {
            'MetricReferences': [
                {
                    'Namespace': 'AWS/ApplicationSignals',
                    'MetricName': 'Error',
                    'Dimensions': [{'Name': 'Service', 'Value': 'test-service'}],
                }
            ]
        }
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
    mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',  # Looking for Latency but only Error exists
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert "Metric 'Latency' not found" in result
    assert 'Available: Error' in result


@pytest.mark.asyncio
async def test_query_service_metrics_client_error(mock_aws_clients):
    """Test query service metrics with client error."""
    mock_aws_clients['appsignals_client'].list_services.side_effect = ClientError(
        error_response={
            'Error': {
                'Code': 'AccessDeniedException',
                'Message': 'User is not authorized',
            }
        },
        operation_name='ListServices',
    )

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert 'AWS Error: User is not authorized' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_failed_query(mock_aws_clients):
    """Test search transaction spans when query fails."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.return_value = {'queryId': 'test-query-id'}
        mock_aws_clients['logs_client'].get_query_results.return_value = {
            'queryId': 'test-query-id',
            'status': 'Failed',
            'statistics': {'error': 'Query syntax error'},
        }

        result = await search_transaction_spans(
            log_group_name='',
            start_time='2024-01-01T00:00:00+00:00',
            end_time='2024-01-01T01:00:00+00:00',
            query_string='invalid query',
            limit=None,
            max_timeout=30,
        )

        assert result['status'] == 'Failed'


@pytest.mark.asyncio
async def test_get_slo_client_error(mock_aws_clients):
    """Test get_slo with client error."""
    mock_aws_clients['appsignals_client'].get_service_level_objective.side_effect = ClientError(
        error_response={
            'Error': {
                'Code': 'ResourceNotFoundException',
                'Message': 'SLO not found',
            }
        },
        operation_name='GetServiceLevelObjective',
    )

    result = await get_slo('test-slo-id')

    assert 'AWS Error: SLO not found' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_empty_log_group(mock_aws_clients):
    """Test search transaction spans with empty log group defaults to aws/spans."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.return_value = {'queryId': 'test-query-id'}
        mock_aws_clients['logs_client'].get_query_results.return_value = {
            'queryId': 'test-query-id',
            'status': 'Complete',
            'results': [],
        }

        await search_transaction_spans(
            log_group_name='',  # Empty string should default to 'aws/spans'
            start_time='2024-01-01T00:00:00+00:00',
            end_time='2024-01-01T01:00:00+00:00',
            query_string='fields @timestamp',
            limit=None,
            max_timeout=30,
        )

        # Verify start_query was called with default 'aws/spans'
        mock_aws_clients['logs_client'].start_query.assert_called()
        call_args = mock_aws_clients['logs_client'].start_query.call_args[1]
        assert 'aws/spans' in call_args['logGroupNames']


@pytest.mark.asyncio
async def test_list_slis_no_services(mock_aws_clients):
    """Test list_slis when no services exist."""
    mock_aws_clients['appsignals_client'].list_services.return_value = {'ServiceSummaries': []}

    result = await list_slis(hours=24)

    assert 'No services found in Application Signals.' in result


@pytest.mark.asyncio
async def test_get_slo_with_calendar_interval(mock_aws_clients):
    """Test get_slo with calendar interval in goal."""
    mock_slo_response = {
        'Slo': {
            'Name': 'test-slo-calendar',
            'Goal': {
                'AttainmentGoal': 99.5,
                'Interval': {
                    'CalendarInterval': {
                        'Duration': 1,
                        'DurationUnit': 'MONTH',
                        'StartTime': '2024-01-01T00:00:00Z',
                    }
                },
            },
        }
    }

    mock_aws_clients[
        'appsignals_client'
    ].get_service_level_objective.return_value = mock_slo_response

    result = await get_slo('test-slo-calendar')

    assert 'Calendar 1 MONTH starting 2024-01-01T00:00:00Z' in result


@pytest.mark.asyncio
async def test_query_service_metrics_different_periods(mock_aws_clients):
    """Test query service metrics with different time periods."""
    # Test data for different hour ranges
    test_cases = [
        (2, 60),  # 2 hours -> 1 minute period
        (12, 300),  # 12 hours -> 5 minute period
        (48, 3600),  # 48 hours -> 1 hour period
    ]

    for hours, expected_period in test_cases:
        mock_list_response = {
            'ServiceSummaries': [
                {'KeyAttributes': {'Name': 'test-service', 'Type': 'AWS::ECS::Service'}}
            ]
        }

        mock_get_response = {
            'Service': {
                'MetricReferences': [
                    {
                        'Namespace': 'AWS/ApplicationSignals',
                        'MetricName': 'Latency',
                        'Dimensions': [],
                    }
                ]
            }
        }

        mock_metric_response = {
            'Datapoints': [{'Timestamp': datetime.now(timezone.utc), 'Average': 100.0}]
        }

        mock_aws_clients['appsignals_client'].list_services.return_value = mock_list_response
        mock_aws_clients['appsignals_client'].get_service.return_value = mock_get_response
        mock_aws_clients[
            'cloudwatch_client'
        ].get_metric_statistics.return_value = mock_metric_response

        await query_service_metrics(
            service_name='test-service',
            metric_name='Latency',
            statistic='Average',
            extended_statistic='p99',
            hours=hours,
        )

        # Verify the period was set correctly
        call_args = mock_aws_clients['cloudwatch_client'].get_metric_statistics.call_args[1]
        assert call_args['Period'] == expected_period


@pytest.mark.asyncio
async def test_query_service_metrics_general_exception(mock_aws_clients):
    """Test query service metrics with unexpected exception."""
    mock_aws_clients['appsignals_client'].list_services.side_effect = Exception('Unexpected error')

    result = await query_service_metrics(
        service_name='test-service',
        metric_name='Latency',
        statistic='Average',
        extended_statistic='p99',
        hours=1,
    )

    assert 'Error: Unexpected error' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_general_exception(mock_aws_clients):
    """Test search transaction spans with general exception."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.side_effect = Exception('Query failed')

        with pytest.raises(Exception) as exc_info:
            await search_transaction_spans(
                log_group_name='aws/spans',
                start_time='2024-01-01T00:00:00+00:00',
                end_time='2024-01-01T01:00:00+00:00',
                query_string='fields @timestamp',
                limit=100,
                max_timeout=30,
            )

        assert 'Query failed' in str(exc_info.value)


@pytest.mark.asyncio
async def test_list_monitored_services_with_attributes_branch(mock_aws_clients):
    """Test list_monitored_services with key attributes that trigger the branch."""
    mock_response = {
        'ServiceSummaries': [
            {
                'KeyAttributes': {}  # Empty attributes to test the branch
            }
        ]
    }

    mock_aws_clients['appsignals_client'].list_services.return_value = mock_response

    result = await list_monitored_services()

    assert 'Application Signals Services (1 total)' in result
    assert 'Key Attributes:' not in result  # Should not show when empty


@pytest.mark.asyncio
async def test_get_trace_summaries_paginated_with_limit(mock_aws_clients):
    """Test get_trace_summaries_paginated when it hits the max_traces limit."""
    # Mock responses with more traces than the limit
    mock_response_1 = {
        'TraceSummaries': [{'Id': f'trace-{i}', 'Duration': 100} for i in range(10)],
        'NextToken': 'token1',
    }
    mock_response_2 = {
        'TraceSummaries': [{'Id': f'trace-{i}', 'Duration': 100} for i in range(10, 15)]
    }

    mock_aws_clients['xray_client'].get_trace_summaries.side_effect = [
        mock_response_1,
        mock_response_2,
    ]

    # Test with max_traces=12
    traces = get_trace_summaries_paginated(
        mock_aws_clients['xray_client'],
        datetime.now(timezone.utc),
        datetime.now(timezone.utc),
        'service("test")',
        max_traces=12,
    )

    # The function continues until it gets all traces from the current page
    # before checking the limit, so we might get more than max_traces
    assert len(traces) >= 12  # Should have at least the limit


@pytest.mark.asyncio
async def test_get_slo_with_period_based_sli_full_details(mock_aws_clients):
    """Test get_slo with comprehensive period-based SLI configuration."""
    mock_response = {
        'Slo': {
            'Name': 'test-slo',
            'Arn': 'arn:aws:slo:test',
            'Description': 'Test SLO',
            'EvaluationType': 'PERIOD_BASED',
            'CreatedTime': datetime.now(timezone.utc),
            'LastUpdatedTime': datetime.now(timezone.utc),
            'Goal': {
                'AttainmentGoal': 99.9,
                'WarningThreshold': 95,
                'Interval': {
                    'CalendarInterval': {
                        'Duration': 1,
                        'DurationUnit': 'MONTH',
                        'StartTime': datetime.now(timezone.utc),
                    }
                },
            },
            'Sli': {
                'SliMetric': {
                    'KeyAttributes': {'Service': 'test-service', 'Environment': 'prod'},
                    'OperationName': 'GetItem',
                    'MetricType': 'LATENCY',
                    'MetricDataQueries': [
                        {
                            'Id': 'query1',
                            'MetricStat': {
                                'Metric': {
                                    'Namespace': 'AWS/ApplicationSignals',
                                    'MetricName': 'Latency',
                                    'Dimensions': [
                                        {'Name': 'Service', 'Value': 'test-service'},
                                        {'Name': 'Operation', 'Value': 'GetItem'},
                                    ],
                                },
                                'Period': 300,
                                'Stat': 'p99',
                                'Unit': 'Milliseconds',
                            },
                            'ReturnData': True,
                        },
                        {'Id': 'query2', 'Expression': 'query1 * 2', 'ReturnData': False},
                    ],
                    'DependencyConfig': {
                        'DependencyKeyAttributes': {
                            'RemoteService': 'downstream-service',
                            'RemoteEnvironment': 'prod',
                        },
                        'DependencyOperationName': 'ProcessRequest',
                    },
                },
                'MetricThreshold': 1000,
                'ComparisonOperator': 'LessThan',
            },
            'BurnRateConfigurations': [
                {'LookBackWindowMinutes': 5},
                {'LookBackWindowMinutes': 60},
            ],
        }
    }

    mock_aws_clients['appsignals_client'].get_service_level_objective.return_value = mock_response

    result = await get_slo('test-slo-id')

    # Verify all sections are present
    assert 'Service Level Objective Details' in result
    assert 'Goal Configuration' in result
    assert 'Calendar 1 MONTH' in result
    assert 'Period-Based SLI Configuration' in result
    assert 'Key Attributes:' in result
    assert 'Service: test-service' in result
    assert 'Operation Name: GetItem' in result
    assert 'Metric Data Queries:' in result
    assert 'Query ID: query1' in result
    assert 'Namespace: AWS/ApplicationSignals' in result
    assert 'Dimensions:' in result
    assert 'Expression: query1 * 2' in result
    assert 'ReturnData: False' in result
    assert 'Dependency Configuration:' in result
    assert 'RemoteService: downstream-service' in result
    assert 'Dependency Operation: ProcessRequest' in result
    assert 'Burn Rate Configurations:' in result


@pytest.mark.asyncio
async def test_get_slo_with_request_based_sli_full_details(mock_aws_clients):
    """Test get_slo with comprehensive request-based SLI configuration."""
    mock_response = {
        'Slo': {
            'Name': 'test-slo-rbs',
            'Arn': 'arn:aws:slo:test-rbs',
            'Goal': {
                'AttainmentGoal': 99.5,
                'Interval': {'RollingInterval': {'Duration': 7, 'DurationUnit': 'DAY'}},
            },
            'RequestBasedSli': {
                'RequestBasedSliMetric': {
                    'KeyAttributes': {'Service': 'api-service', 'Type': 'AWS::Lambda::Function'},
                    'OperationName': 'ProcessOrder',
                    'MetricType': 'AVAILABILITY',
                    'MetricDataQueries': [
                        {
                            'Id': 'success',
                            'MetricStat': {
                                'Metric': {
                                    'Namespace': 'AWS/Lambda',
                                    'MetricName': 'Success',
                                    'Dimensions': [
                                        {'Name': 'FunctionName', 'Value': 'process-order'}
                                    ],
                                },
                                'Period': 60,
                                'Stat': 'Sum',
                            },
                        },
                        {
                            'Id': 'errors',
                            'MetricStat': {
                                'Metric': {
                                    'Namespace': 'AWS/Lambda',
                                    'MetricName': 'Errors',
                                    'Dimensions': [
                                        {'Name': 'FunctionName', 'Value': 'process-order'}
                                    ],
                                },
                                'Period': 60,
                                'Stat': 'Sum',
                                'Unit': 'Count',
                            },
                        },
                        {'Id': 'availability', 'Expression': 'success / (success + errors) * 100'},
                    ],
                    'DependencyConfig': {
                        'DependencyKeyAttributes': {'Database': 'orders-db'},
                        'DependencyOperationName': 'Query',
                    },
                },
                'MetricThreshold': 99.0,
                'ComparisonOperator': 'GreaterThan',
            },
        }
    }

    mock_aws_clients['appsignals_client'].get_service_level_objective.return_value = mock_response

    result = await get_slo('test-slo-rbs-id')

    # Verify request-based sections
    assert 'Request-Based SLI Configuration:' in result
    assert 'api-service' in result
    assert 'ProcessOrder' in result
    assert 'AVAILABILITY' in result
    assert 'Expression: success / (success + errors) * 100' in result
    assert 'Dependency Configuration:' in result
    assert 'Database: orders-db' in result
    assert 'Unit: Count' in result


@pytest.mark.asyncio
async def test_get_slo_general_exception(mock_aws_clients):
    """Test get_slo with general exception."""
    mock_aws_clients['appsignals_client'].get_service_level_objective.side_effect = Exception(
        'Unexpected error'
    )

    result = await get_slo('test-slo-id')

    assert 'Error: Unexpected error' in result


@pytest.mark.asyncio
async def test_search_transaction_spans_with_none_log_group(mock_aws_clients):
    """Test search_transaction_spans when log_group_name is None."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.return_value = {'queryId': 'test-query-id'}
        mock_aws_clients['logs_client'].get_query_results.return_value = {
            'queryId': 'test-query-id',
            'status': 'Complete',
            'results': [],
        }

        # Pass None for log_group_name to test the default handling
        await search_transaction_spans(
            log_group_name=None,  # type: ignore
            start_time='2024-01-01T00:00:00+00:00',
            end_time='2024-01-01T01:00:00+00:00',
            query_string='fields @timestamp',
            limit=100,
            max_timeout=30,
        )

        # Verify it used the default log group
        call_args = mock_aws_clients['logs_client'].start_query.call_args[1]
        assert 'aws/spans' in call_args['logGroupNames']


@pytest.mark.asyncio
async def test_search_transaction_spans_complete_with_statistics(mock_aws_clients):
    """Test search_transaction_spans when query completes with detailed statistics."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.check_transaction_search_enabled'
    ) as mock_check:
        mock_check.return_value = (True, 'CloudWatchLogs', 'ACTIVE')
        mock_aws_clients['logs_client'].start_query.return_value = {'queryId': 'test-query-id'}

        # First return Running, then Complete
        mock_aws_clients['logs_client'].get_query_results.side_effect = [
            {'queryId': 'test-query-id', 'status': 'Running'},
            {
                'queryId': 'test-query-id',
                'status': 'Complete',
                'statistics': {
                    'recordsMatched': 100,
                    'recordsScanned': 1000,
                    'bytesScanned': 50000,
                },
                'results': [
                    [
                        {'field': 'spanId', 'value': 'span1'},
                        {'field': '@timestamp', 'value': '2024-01-01 00:00:00'},
                    ]
                ],
            },
        ]

        result = await search_transaction_spans(
            log_group_name='aws/spans',
            start_time='2024-01-01T00:00:00+00:00',
            end_time='2024-01-01T01:00:00+00:00',
            query_string='fields @timestamp, spanId',
            limit=100,
            max_timeout=30,
        )

        assert result['status'] == 'Complete'
        assert result['statistics']['recordsMatched'] == 100
        assert len(result['results']) == 1


@pytest.mark.asyncio
async def test_list_slis_general_exception(mock_aws_clients):
    """Test list_slis with general exception."""
    mock_aws_clients['appsignals_client'].list_services.side_effect = Exception(
        'Service unavailable'
    )

    result = await list_slis(hours=24)

    assert 'Error getting SLI status: Service unavailable' in result


@pytest.mark.asyncio
async def test_query_sampled_traces_with_defaults(mock_aws_clients):
    """Test query_sampled_traces with default start_time and end_time."""
    mock_trace_response = {
        'TraceSummaries': [
            {
                'Id': 'trace1',
                'Duration': 100,
                'HasError': True,
                'ErrorRootCauses': [
                    {
                        'Services': [
                            {
                                'Name': 'test-service',
                                'Names': ['test-service'],
                                'Type': 'AWS::ECS::Service',
                                'AccountId': '123456789012',
                                'EntityPath': [
                                    {'Name': 'test-service', 'Coverage': 1.0, 'Remote': False}
                                ],
                                'Inferred': False,
                            }
                        ],
                        'ClientImpacting': True,
                    }
                ],
            }
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.return_value = mock_trace_response['TraceSummaries']

        # Call without start_time and end_time to test defaults
        result_json = await query_sampled_traces(
            filter_expression='service("test-service")',
            start_time=None,
            end_time=None,
            region='us-east-1',
        )

        result = json.loads(result_json)
        assert result['TraceCount'] == 1
        assert result['TraceSummaries'][0]['HasError'] is True

        # Verify the time window was set to 3 hours
        call_args = mock_paginated.call_args[0]
        time_diff = call_args[2] - call_args[1]  # end_time - start_time
        assert 2.9 < time_diff.total_seconds() / 3600 < 3.1  # Approximately 3 hours


@pytest.mark.asyncio
async def test_query_sampled_traces_with_annotations(mock_aws_clients):
    """Test query_sampled_traces with annotations filtering."""
    mock_trace = {
        'Id': 'trace1',
        'Duration': 100,
        'Annotations': {
            'aws.local.operation': 'GetItem',
            'aws.remote.operation': 'Query',
            'custom.field': 'should-be-filtered',
            'another.field': 'also-filtered',
        },
        'Users': [
            {'UserName': 'user1', 'ServiceIds': []},
            {'UserName': 'user2', 'ServiceIds': []},
            {'UserName': 'user3', 'ServiceIds': []},  # Should be limited to 2
        ],
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.return_value = [mock_trace]

        result_json = await query_sampled_traces(
            start_time='2024-01-01T00:00:00Z',
            end_time='2024-01-01T01:00:00Z',
            filter_expression='service("test")',
        )

        result = json.loads(result_json)
        trace_summary = result['TraceSummaries'][0]

        # Check annotations were filtered
        assert 'Annotations' in trace_summary
        assert 'aws.local.operation' in trace_summary['Annotations']
        assert 'aws.remote.operation' in trace_summary['Annotations']
        assert 'custom.field' not in trace_summary['Annotations']

        # Check users were limited
        assert len(trace_summary['Users']) == 2


@pytest.mark.asyncio
async def test_query_sampled_traces_with_fault_causes(mock_aws_clients):
    """Test query_sampled_traces with fault root causes."""
    mock_trace = {
        'Id': 'trace1',
        'Duration': 100,
        'HasFault': True,
        'FaultRootCauses': [
            {'Services': [{'Name': 'service1', 'Exceptions': [{'Message': 'Test fault error'}]}]},
            {'Services': [{'Name': 'service2'}]},
            {'Services': [{'Name': 'service3'}]},
            {'Services': [{'Name': 'service4'}]},  # Should be limited to 3
        ],
        'ResponseTimeRootCauses': [{'Services': [{'Name': 'slow-service'}]}],
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.return_value = [mock_trace]

        result_json = await query_sampled_traces(
            start_time='2024-01-01T00:00:00Z', end_time='2024-01-01T01:00:00Z'
        )

        result = json.loads(result_json)
        trace_summary = result['TraceSummaries'][0]

        # Check root causes were limited to 3
        assert len(trace_summary['FaultRootCauses']) == 3
        assert 'ResponseTimeRootCauses' in trace_summary


@pytest.mark.asyncio
async def test_query_sampled_traces_general_exception(mock_aws_clients):
    """Test query_sampled_traces with general exception."""
    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.side_effect = Exception('Trace query failed')

        result_json = await query_sampled_traces(
            start_time='2024-01-01T00:00:00Z', end_time='2024-01-01T01:00:00Z'
        )

        result = json.loads(result_json)
        assert 'error' in result
        assert 'Trace query failed' in result['error']


@pytest.mark.asyncio
async def test_query_sampled_traces_datetime_conversion(mock_aws_clients):
    """Test query_sampled_traces with datetime objects that need conversion."""
    # The convert_datetime function in server.py only processes top-level fields,
    # not nested datetime objects. Let's test with a datetime at the top level.
    mock_trace = {
        'Id': 'trace1',
        'Duration': 100,
        'Http': {'HttpStatus': 200, 'HttpMethod': 'GET'},
        'StartTime': datetime.now(timezone.utc),  # This will be processed by convert_datetime
        'EndTime': datetime.now(timezone.utc) + timedelta(minutes=1),
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.return_value = [mock_trace]

        result_json = await query_sampled_traces(
            start_time='2024-01-01T00:00:00Z', end_time='2024-01-01T01:00:00Z'
        )

        # Should not raise JSON serialization error
        result = json.loads(result_json)
        assert result['TraceCount'] == 1
        # The datetime fields should have been converted during processing
        trace_summary = result['TraceSummaries'][0]
        assert (
            'StartTime' not in trace_summary
        )  # These fields are not included in the simplified output
        assert 'EndTime' not in trace_summary


@pytest.mark.asyncio
async def test_query_sampled_traces_deduplication(mock_aws_clients):
    """Test query_sampled_traces deduplicates traces with same fault message.

    Note: Only FaultRootCauses are deduplicated, not ErrorRootCauses.
    This is because the primary use case is investigating server faults (5xx errors),
    not client errors (4xx).
    """
    # Create 5 traces with the same fault message
    mock_traces = [
        {
            'Id': f'trace{i}',
            'Duration': 100 + i * 10,
            'ResponseTime': 95 + i * 10,
            'HasFault': True,
            'FaultRootCauses': [
                {
                    'Services': [
                        {
                            'Name': 'test-service',
                            'Exceptions': [{'Message': 'Database connection timeout'}],
                        }
                    ]
                }
            ],
        }
        for i in range(1, 6)
    ]

    # Add 2 traces with ErrorRootCauses (these should NOT be deduplicated)
    mock_traces.extend(
        [
            {
                'Id': 'trace6',
                'Duration': 200,
                'HasError': True,
                'ErrorRootCauses': [
                    {
                        'Services': [
                            {
                                'Name': 'api-service',
                                'Exceptions': [{'Message': 'Invalid API key'}],
                            }
                        ]
                    }
                ],
            },
            {
                'Id': 'trace7',
                'Duration': 210,
                'HasError': True,
                'ErrorRootCauses': [
                    {
                        'Services': [
                            {
                                'Name': 'api-service',
                                'Exceptions': [{'Message': 'Invalid API key'}],
                            }
                        ]
                    }
                ],
            },
        ]
    )

    # Add 2 healthy traces
    mock_traces.extend(
        [
            {
                'Id': 'trace8',
                'Duration': 50,
                'ResponseTime': 45,
                'HasError': False,
                'HasFault': False,
            },
            {
                'Id': 'trace9',
                'Duration': 55,
                'ResponseTime': 50,
                'HasError': False,
                'HasFault': False,
            },
        ]
    )

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.trace_tools.get_trace_summaries_paginated'
    ) as mock_paginated:
        mock_paginated.return_value = mock_traces

        result_json = await query_sampled_traces(
            start_time='2024-01-01T00:00:00Z', end_time='2024-01-01T01:00:00Z'
        )

        result = json.loads(result_json)

        # Verify deduplication worked - should only have 5 traces
        # 1 for database timeout fault (deduplicated from 5)
        # 2 for API key errors (NOT deduplicated - only faults are deduped)
        # 2 healthy traces (not deduplicated)
        assert result['TraceCount'] == 5
        assert len(result['TraceSummaries']) == 5

        # Verify deduplication stats
        assert 'DeduplicationStats' in result
        assert result['DeduplicationStats']['OriginalTraceCount'] == 9
        assert result['DeduplicationStats']['DuplicatesRemoved'] == 4  # 9 - 5 = 4
        assert (
            result['DeduplicationStats']['UniqueFaultMessages'] == 1
        )  # Only counting FaultRootCauses

        # Find the trace with fault
        db_trace = next(
            (
                t
                for t in result['TraceSummaries']
                if t.get('FaultRootCauses')
                and any(
                    'Database connection timeout' in str(s.get('Exceptions', []))
                    for cause in t['FaultRootCauses']
                    for s in cause.get('Services', [])
                )
            ),
            None,
        )
        assert db_trace is not None
        assert db_trace['HasFault'] is True

        # Verify both error traces are present (not deduplicated)
        error_traces = [
            t
            for t in result['TraceSummaries']
            if t.get('ErrorRootCauses')
            and any(
                'Invalid API key' in str(s.get('Exceptions', []))
                for cause in t['ErrorRootCauses']
                for s in cause.get('Services', [])
            )
        ]
        assert len(error_traces) == 2  # Both error traces should be kept
        assert all(t['HasError'] is True for t in error_traces)

        # Verify healthy traces are included
        healthy_count = sum(
            1
            for t in result['TraceSummaries']
            if not t.get('HasError') and not t.get('HasFault') and not t.get('HasThrottle')
        )
        assert healthy_count == 2


def test_main_success(mock_aws_clients):
    """Test main function normal execution."""
    with patch('awslabs.cloudwatch_appsignals_mcp_server.server.mcp') as mock_mcp:
        main()
        mock_mcp.run.assert_called_once_with(transport='stdio')


def test_main_exception(mock_aws_clients):
    """Test main function with general exception."""
    with patch('awslabs.cloudwatch_appsignals_mcp_server.server.mcp') as mock_mcp:
        mock_mcp.run.side_effect = Exception('Server error')

        with pytest.raises(Exception) as exc_info:
            main()

        assert 'Server error' in str(exc_info.value)


def test_main_entry_point(mock_aws_clients):
    """Test the if __name__ == '__main__' entry point."""
    # The __main__ block is simple and just calls main()
    # We can't easily test it without executing the module
    # So we'll just ensure the main() function works
    # The actual line 1346 will be covered when the module is imported
    # during normal test execution

    # Instead, let's just verify the main function exists and is callable
    from awslabs.cloudwatch_appsignals_mcp_server.server import main

    assert callable(main)

    # And verify that running main with mocked mcp doesn't raise
    with patch('awslabs.cloudwatch_appsignals_mcp_server.server.mcp') as mock_mcp:
        mock_mcp.run.side_effect = KeyboardInterrupt()
        # Should handle KeyboardInterrupt gracefully
        main()


@pytest.mark.asyncio
async def test_analyze_canary_failures_no_runs(mock_aws_clients):
    """Test analyze_canary_failures when no runs are found."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': []}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {
        'Canary': {'Name': 'test-canary'}
    }

    result = await analyze_canary_failures('test-canary', 'us-east-1')

    assert 'No run history found for test-canary' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_healthy_canary(mock_aws_clients):
    """Test analyze_canary_failures with healthy canary."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'run1',
            'Status': {'State': 'PASSED'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {
        'Canary': {'Name': 'test-canary'}
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        mock_insights.return_value = 'Telemetry insights available'

        result = await analyze_canary_failures('test-canary', 'us-east-1')

        assert 'Canary is healthy - no failures since last success' in result
        assert '🔍 Comprehensive Failure Analysis for test-canary' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_telemetry_unavailable(mock_aws_clients):
    """Test analyze_canary_failures when telemetry is unavailable."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'run1',
            'Status': {'State': 'PASSED'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {
        'Canary': {'Name': 'test-canary'}
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        mock_insights.side_effect = Exception('Telemetry API error')

        result = await analyze_canary_failures('test-canary', 'us-east-1')

        assert 'Telemetry API unavailable: Telemetry API error' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_with_failures(mock_aws_clients):
    """Test analyze_canary_failures with actual failures."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run-1',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timeout'},
            'Timeline': {'Started': '2024-01-01T01:00:00Z'},
        },
        {
            'Id': 'failed-run-2',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timeout'},
            'Timeline': {'Started': '2024-01-01T00:30:00Z'},
        },
        {
            'Id': 'success-run',
            'Status': {'State': 'PASSED'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        },
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 artifacts
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/screenshot.png'},
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/logs.txt'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            with patch(
                'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_screenshots'
            ) as mock_screenshots:
                with patch(
                    'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_log_files'
                ) as mock_logs:
                    mock_insights.return_value = 'Telemetry insights'
                    mock_har.return_value = {
                        'failed_requests': 2,
                        'total_requests': 10,
                        'request_details': [
                            {'url': 'https://example.com', 'status': 500, 'time': 1000}
                        ],
                    }
                    mock_screenshots.return_value = {'insights': ['Screenshot analysis']}
                    mock_logs.return_value = {'insights': ['Log analysis']}

                    result = await analyze_canary_failures('test-canary', 'us-east-1')

                    assert 'Found 2 consecutive failures since last success' in result
                    assert 'All failures have same cause: Navigation timeout' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_iam_analysis(mock_aws_clients):
    """Test analyze_canary_failures with IAM-related failures."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Access denied'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_iam_role_and_policies'
        ) as mock_iam:
            with patch(
                'awslabs.cloudwatch_appsignals_mcp_server.server.check_resource_arns_correct'
            ) as mock_arn:
                mock_insights.return_value = 'Telemetry insights'
                mock_iam.return_value = {
                    'status': 'issues_found',
                    'checks': {'role_exists': 'PASS', 'policies_attached': 'FAIL'},
                    'issues_found': ['Missing S3 permissions'],
                    'recommendations': ['Add S3 read permissions'],
                }
                mock_arn.return_value = {
                    'correct': False,
                    'error': 'Invalid bucket ARN',
                    'issues': ['Bucket name mismatch'],
                }

                result = await analyze_canary_failures('test-canary', 'us-east-1')

                assert 'RUNNING COMPREHENSIVE IAM ANALYSIS' in result
                assert 'IAM Role Analysis Status: issues_found' in result
                assert 'ALL IAM ISSUES FOUND (2 total):' in result
                assert 'IAM Policy: Missing S3 permissions' in result
                assert 'Resource ARN: Bucket name mismatch' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_enospc_error(mock_aws_clients):
    """Test analyze_canary_failures with ENOSPC error."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'ENOSPC: no space left on device'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.extract_disk_memory_usage_metrics'
        ) as mock_metrics:
            mock_insights.return_value = 'Telemetry insights'
            mock_metrics.return_value = {
                'maxEphemeralStorageUsageInMb': 512.5,
                'maxEphemeralStorageUsagePercent': 95.2,
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert 'DISK USAGE ROOT CAUSE ANALYSIS:' in result
            assert 'Storage: 512.5 MB peak' in result
            assert 'Usage: 95.2% peak' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_protocol_error(mock_aws_clients):
    """Test analyze_canary_failures with protocol error."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {
                'State': 'FAILED',
                'StateReason': 'Protocol error (Target.activateTarget): Session closed',
            },
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.extract_disk_memory_usage_metrics'
        ) as mock_metrics:
            mock_insights.return_value = 'Telemetry insights'
            mock_metrics.return_value = {'maxSyntheticsMemoryUsageInMB': 256.8}

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert 'MEMORY USAGE ROOT CAUSE ANALYSIS:' in result
            assert 'Memory: 256.8 MB peak' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_navigation_timeout_with_har(mock_aws_clients):
    """Test analyze_canary_failures with navigation timeout and HAR analysis."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timed out after 30000ms'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return HAR files
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            mock_har.return_value = {
                'failed_requests': 5,
                'total_requests': 10,
                'request_details': [
                    {'url': 'https://example.com/slow', 'status': 200, 'time': 5000}
                ],
                'insights': [
                    'Slow DNS resolution detected',
                    'High server response time',
                    'Network connectivity issues',
                    'Resource loading delays',
                    'JavaScript execution timeout',
                ],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert '🔍 Comprehensive Failure Analysis for test-canary' in result
            assert 'Slow DNS resolution detected' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_s3_exception(mock_aws_clients):
    """Test analyze_canary_failures when S3 operations fail."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    mock_aws_clients['s3_client'].list_objects_v2.side_effect = Exception('S3 access denied')

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_canary_logs_with_time_window'
        ) as mock_logs:
            mock_insights.return_value = 'Telemetry insights'
            mock_logs.return_value = {
                'status': 'success',
                'time_window': '2024-01-01 00:00:00 - 2024-01-01 00:05:00',
                'total_events': 5,
                'error_events': [
                    {'timestamp': datetime.now(timezone.utc), 'message': 'Test error message'}
                ],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            # Should fall back to CloudWatch Logs analysis when S3 fails
            assert '⚠️ Artifacts not available - Checking CloudWatch Logs for root cause' in result
            assert 'CLOUDWATCH LOGS ANALYSIS' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_visual_variation(mock_aws_clients):
    """Test analyze_canary_failures with visual variation error."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Visual variation detected'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_code') as mock_code:
            mock_insights.return_value = 'Telemetry insights'
            mock_code.return_value = {'code_content': 'const synthetics = require("Synthetics");'}

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert 'VISUAL MONITORING ISSUE DETECTED' in result
            assert 'Website UI changed - not a technical failure' in result
            assert 'canary code:' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_get_canary_code_exception(mock_aws_clients):
    """Test analyze_canary_failures when get_canary_code fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_code') as mock_code:
            mock_insights.return_value = 'Telemetry insights'
            # Make get_canary_code raise an exception
            mock_code.side_effect = Exception('Code retrieval failed')

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert 'Note: Could not retrieve canary code: Code retrieval failed' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_iam_analysis_exception(mock_aws_clients):
    """Test analyze_canary_failures when IAM analysis fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Access denied'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_iam_role_and_policies'
        ) as mock_iam:
            mock_insights.return_value = 'Telemetry insights'
            # Make IAM analysis raise an exception
            mock_iam.side_effect = Exception('IAM analysis failed')

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert '⚠️ IAM analysis failed: IAM analysis failed' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_disk_usage_exception(mock_aws_clients):
    """Test analyze_canary_failures when disk usage analysis fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'ENOSPC: no space left on device'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.extract_disk_memory_usage_metrics'
        ) as mock_metrics:
            mock_insights.return_value = 'Telemetry insights'
            # Make disk usage analysis raise an exception
            mock_metrics.side_effect = Exception('Disk usage analysis failed')

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert (
                '⚠️ Could not generate disk usage debugging code: Disk usage analysis failed'
                in result
            )


@pytest.mark.asyncio
async def test_analyze_canary_failures_memory_usage_exception(mock_aws_clients):
    """Test analyze_canary_failures when memory usage analysis fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {
                'State': 'FAILED',
                'StateReason': 'Protocol error (Target.activateTarget): Session closed',
            },
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.extract_disk_memory_usage_metrics'
        ) as mock_metrics:
            mock_insights.return_value = 'Telemetry insights'
            # Make memory usage analysis raise an exception
            mock_metrics.side_effect = Exception('Memory usage analysis failed')

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert (
                '⚠️ Could not collect memory usage metrics: Memory usage analysis failed' in result
            )


@pytest.mark.asyncio
async def test_analyze_canary_failures_har_timeout_exception(mock_aws_clients):
    """Test analyze_canary_failures when HAR timeout analysis fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timed out after 30000ms'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return HAR files
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            # Make HAR analysis raise an exception
            mock_har.side_effect = Exception('HAR analysis failed')

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert '⚠️ HAR analysis failed: HAR analysis failed' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_success_artifacts_exception(mock_aws_clients):
    """Test analyze_canary_failures when success artifacts retrieval fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        },
        {
            'Id': 'success-run',
            'Status': {'State': 'PASSED'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        },
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return failure artifacts but fail on success artifacts
    def s3_side_effect(*args, **kwargs):
        prefix = kwargs.get('Prefix', '')
        if 'success' in prefix or len(prefix.split('/')) > 5:  # Simulate success path failure
            raise Exception('Success artifacts access failed')
        return {
            'Contents': [
                {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
            ]
        }

    mock_aws_clients['s3_client'].list_objects_v2.side_effect = s3_side_effect

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            mock_har.return_value = {
                'failed_requests': 2,
                'total_requests': 10,
                'request_details': [],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            # Should still process failure artifacts even if success artifacts fail
            assert '🔍 Comprehensive Failure Analysis for test-canary' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_no_failure_timestamp(mock_aws_clients):
    """Test analyze_canary_failures when failure has no timestamp."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {},  # No Started timestamp
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        mock_insights.return_value = 'Telemetry insights'

        result = await analyze_canary_failures('test-canary', 'us-east-1')

        assert '📋 No failure timestamp available for targeted log analysis' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_log_analysis_failure(mock_aws_clients):
    """Test analyze_canary_failures when log analysis fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch(
            'awslabs.cloudwatch_appsignals_mcp_server.server.analyze_canary_logs_with_time_window'
        ) as mock_logs:
            mock_insights.return_value = 'Telemetry insights'
            mock_logs.return_value = {
                'status': 'failed',
                'insights': ['Log analysis failed due to missing log group'],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            assert '📋 Log analysis failed due to missing log group' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_main_exception(mock_aws_clients):
    """Test analyze_canary_failures when main function fails."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    # Make get_canary_runs raise an exception
    mock_aws_clients['synthetics_client'].get_canary_runs.side_effect = Exception('API error')

    result = await analyze_canary_failures('test-canary', 'us-east-1')

    assert '❌ Error in comprehensive failure analysis: API error' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_no_har_files_navigation_timeout(mock_aws_clients):
    """Test analyze_canary_failures navigation timeout without HAR files."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timed out after 30000ms'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        mock_insights.return_value = 'Telemetry insights'

        result = await analyze_canary_failures('test-canary', 'us-east-1')

        assert 'NAVIGATION TIMEOUT DETECTED:' in result
        assert 'No HAR files available for detailed analysis' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_artifact_location_without_s3_prefix(mock_aws_clients):
    """Test analyze_canary_failures with artifact location without s3:// prefix."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 'test-bucket/canary/us-east-1/test-canary',  # No s3:// prefix
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return artifacts
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            mock_har.return_value = {
                'failed_requests': 1,
                'total_requests': 5,
                'request_details': [],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            # Should still process artifacts even without s3:// prefix
            assert 'FAILURE ANALYSIS' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_empty_base_path(mock_aws_clients):
    """Test analyze_canary_failures with empty base path."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket',  # Only bucket, no path
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return artifacts
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            mock_har.return_value = {
                'failed_requests': 1,
                'total_requests': 5,
                'request_details': [],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            # Should construct default canary path when base_path is empty
            assert 'FAILURE ANALYSIS' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_multiple_failure_causes(mock_aws_clients):
    """Test analyze_canary_failures with multiple different failure causes."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run-1',
            'Status': {'State': 'FAILED', 'StateReason': 'Navigation timeout'},
            'Timeline': {'Started': '2024-01-01T00:00:00Z'},
        },
        {
            'Id': 'failed-run-2',
            'Status': {'State': 'FAILED', 'StateReason': 'Access denied'},
            'Timeline': {'Started': '2024-01-01T00:01:00Z'},
        },
        {
            'Id': 'success-run',
            'Status': {'State': 'PASSED'},
            'Timeline': {'Started': '2023-12-31T23:59:00Z'},
        },
    ]

    mock_canary = {'Name': 'test-canary', 'ArtifactS3Location': ''}

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        mock_insights.return_value = 'Telemetry insights'

        result = await analyze_canary_failures('test-canary', 'us-east-1')

        assert 'Multiple failure causes (2 different issues):' in result
        assert '1. **Navigation timeout** (1 occurrences)' in result
        assert '2. **Access denied** (1 occurrences)' in result


@pytest.mark.asyncio
async def test_analyze_canary_failures_no_failure_time_fallback(mock_aws_clients):
    """Test analyze_canary_failures fallback when no failure time."""
    from awslabs.cloudwatch_appsignals_mcp_server.server import analyze_canary_failures

    mock_runs = [
        {
            'Id': 'failed-run',
            'Status': {'State': 'FAILED', 'StateReason': 'Test failure'},
            'Timeline': {},  # No Started time
        }
    ]

    mock_canary = {
        'Name': 'test-canary',
        'ArtifactS3Location': 's3://test-bucket/canary/us-east-1/test-canary',
    }

    mock_aws_clients['synthetics_client'].get_canary_runs.return_value = {'CanaryRuns': mock_runs}
    mock_aws_clients['synthetics_client'].get_canary.return_value = {'Canary': mock_canary}

    # Mock S3 to return artifacts
    mock_aws_clients['s3_client'].list_objects_v2.return_value = {
        'Contents': [
            {'Key': 'canary/us-east-1/test-canary/2024/01/01/test.har'},
        ]
    }

    with patch(
        'awslabs.cloudwatch_appsignals_mcp_server.server.get_canary_metrics_and_service_insights'
    ) as mock_insights:
        with patch('awslabs.cloudwatch_appsignals_mcp_server.server.analyze_har_file') as mock_har:
            mock_insights.return_value = 'Telemetry insights'
            mock_har.return_value = {
                'failed_requests': 1,
                'total_requests': 5,
                'request_details': [],
            }

            result = await analyze_canary_failures('test-canary', 'us-east-1')

            # Should use current time when no failure time available
            assert 'FAILURE ANALYSIS' in result


def test_filter_operation_targets_fault_to_availability():
    """Test _filter_operation_targets converts Fault to Availability."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    'MetricType': 'Fault',
                }
            },
        }
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify the MetricType was changed from Fault to Availability
    assert len(operation_targets) == 1
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'Availability'
    assert has_wildcards is False


def test_filter_operation_targets_non_fault_unchanged():
    """Test _filter_operation_targets leaves non-Fault MetricTypes unchanged."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    'MetricType': 'Latency',
                }
            },
        },
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service-2'},
                    'Operation': 'POST /api',
                    'MetricType': 'Error',
                }
            },
        },
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify non-Fault MetricTypes are unchanged
    assert len(operation_targets) == 2
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'Latency'
    assert operation_targets[1]['Data']['ServiceOperation']['MetricType'] == 'Error'
    assert has_wildcards is False


def test_filter_operation_targets_multiple_fault_conversions():
    """Test _filter_operation_targets converts multiple Fault entries to Availability."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'service-1'},
                    'Operation': 'GET /api',
                    'MetricType': 'Fault',
                }
            },
        },
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'service-2'},
                    'Operation': 'POST /api',
                    'MetricType': 'Latency',
                }
            },
        },
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'service-3'},
                    'Operation': 'PUT /api',
                    'MetricType': 'Fault',
                }
            },
        },
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify multiple Fault entries are converted
    assert len(operation_targets) == 3
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'Availability'
    assert operation_targets[1]['Data']['ServiceOperation']['MetricType'] == 'Latency'
    assert operation_targets[2]['Data']['ServiceOperation']['MetricType'] == 'Availability'
    assert has_wildcards is False


def test_filter_operation_targets_with_wildcards():
    """Test _filter_operation_targets detects wildcards and converts Fault to Availability."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': '*payment*'},
                    'Operation': '*GET*',
                    'MetricType': 'Fault',
                }
            },
        }
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify wildcard detection and Fault conversion
    assert len(operation_targets) == 1
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'Availability'
    assert has_wildcards is True


def test_filter_operation_targets_ignores_non_service_operation():
    """Test _filter_operation_targets ignores non-service_operation targets."""
    provided = [
        {
            'Type': 'service',
            'Data': {'Service': {'Type': 'Service', 'Name': 'test-service'}},
        },
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    'MetricType': 'Fault',
                }
            },
        },
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify only service_operation targets are included
    assert len(operation_targets) == 1
    assert operation_targets[0]['Type'] == 'service_operation'
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'Availability'
    assert has_wildcards is False


def test_filter_operation_targets_empty_metric_type():
    """Test _filter_operation_targets handles empty MetricType gracefully."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    'MetricType': '',
                }
            },
        }
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify empty MetricType is unchanged
    assert len(operation_targets) == 1
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == ''
    assert has_wildcards is False


def test_filter_operation_targets_missing_metric_type():
    """Test _filter_operation_targets handles missing MetricType gracefully."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    # MetricType is missing
                }
            },
        }
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify missing MetricType doesn't cause errors
    assert len(operation_targets) == 1
    # MetricType should remain missing (empty string from .get())
    assert operation_targets[0]['Data']['ServiceOperation'].get('MetricType', '') == ''
    assert has_wildcards is False


def test_filter_operation_targets_case_sensitive():
    """Test _filter_operation_targets is case-sensitive for Fault conversion."""
    provided = [
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service'},
                    'Operation': 'GET /api',
                    'MetricType': 'fault',  # lowercase
                }
            },
        },
        {
            'Type': 'service_operation',
            'Data': {
                'ServiceOperation': {
                    'Service': {'Type': 'Service', 'Name': 'test-service-2'},
                    'Operation': 'POST /api',
                    'MetricType': 'FAULT',  # uppercase
                }
            },
        },
    ]

    operation_targets, has_wildcards = _filter_operation_targets(provided)

    # Verify only exact case "Fault" is converted
    assert len(operation_targets) == 2
    assert operation_targets[0]['Data']['ServiceOperation']['MetricType'] == 'fault'  # unchanged
    assert operation_targets[1]['Data']['ServiceOperation']['MetricType'] == 'FAULT'  # unchanged
    assert has_wildcards is False

```
Page 381/384FirstPrevNextLast