This is page 702 of 717. Use http://codebase.md/awslabs/mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .devcontainer
│ └── devcontainer.json
├── .github
│ ├── actions
│ │ ├── build-and-push-container-image
│ │ │ └── action.yml
│ │ └── clear-space-ubuntu-latest-agressively
│ │ └── action.yml
│ ├── codecov.yml
│ ├── CODEOWNERS
│ ├── dependabot.yml
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── documentation.yml
│ │ ├── feature_request.yml
│ │ ├── rfc.yml
│ │ └── support_awslabs_mcp_servers.yml
│ ├── pull_request_template.md
│ ├── SECURITY
│ ├── SUPPORT
│ └── workflows
│ ├── aws-api-mcp-upgrade-version.yml
│ ├── bandit-requirements.txt
│ ├── bandit.yml
│ ├── cfn_nag.yml
│ ├── check-gh-pages-builds.yml
│ ├── check-license-header-hash.txt
│ ├── check-license-header-slash.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-applicationsignals-mcp-server.md
│ │ │ ├── cloudwatch-mcp-server.md
│ │ │ ├── code-doc-gen-mcp-server.md
│ │ │ ├── core-mcp-server.md
│ │ │ ├── cost-explorer-mcp-server.md
│ │ │ ├── document-loader-mcp-server.md
│ │ │ ├── documentdb-mcp-server.md
│ │ │ ├── dynamodb-mcp-server.md
│ │ │ ├── ecs-mcp-server.md
│ │ │ ├── eks-mcp-server.md
│ │ │ ├── elasticache-mcp-server.md
│ │ │ ├── finch-mcp-server.md
│ │ │ ├── frontend-mcp-server.md
│ │ │ ├── git-repo-research-mcp-server.md
│ │ │ ├── healthlake-mcp-server.md
│ │ │ ├── iam-mcp-server.md
│ │ │ ├── kendra-index-mcp-server.md
│ │ │ ├── lambda-tool-mcp-server.md
│ │ │ ├── memcached-mcp-server.md
│ │ │ ├── mysql-mcp-server.md
│ │ │ ├── nova-canvas-mcp-server.md
│ │ │ ├── openapi-mcp-server.md
│ │ │ ├── postgres-mcp-server.md
│ │ │ ├── prometheus-mcp-server.md
│ │ │ ├── redshift-mcp-server.md
│ │ │ ├── s3-tables-mcp-server.md
│ │ │ ├── stepfunctions-tool-mcp-server.md
│ │ │ ├── syntheticdata-mcp-server.md
│ │ │ ├── terraform-mcp-server.md
│ │ │ ├── timestream-for-influxdb-mcp-server.md
│ │ │ ├── valkey-mcp-server.md
│ │ │ └── well-architected-security-mcp-server.mdx
│ │ └── vibe_coding.md
│ ├── docusaurus.config.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── sidebars.ts
│ ├── src
│ │ ├── components
│ │ │ ├── HomepageFeatures
│ │ │ │ └── styles.module.css
│ │ │ └── ServerCards
│ │ │ ├── index.tsx
│ │ │ └── styles.module.css
│ │ ├── css
│ │ │ ├── custom.css
│ │ │ └── doc-override.css
│ │ └── pages
│ │ ├── index.module.css
│ │ └── servers.tsx
│ ├── static
│ │ ├── .nojekyll
│ │ ├── assets
│ │ │ ├── icons
│ │ │ │ ├── activity.svg
│ │ │ │ ├── book-open.svg
│ │ │ │ ├── cpu.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── dollar-sign.svg
│ │ │ │ ├── help-circle.svg
│ │ │ │ ├── key.svg
│ │ │ │ ├── server.svg
│ │ │ │ ├── share-2.svg
│ │ │ │ ├── tool.svg
│ │ │ │ └── zap.svg
│ │ │ └── server-cards.json
│ │ └── img
│ │ ├── aws-logo.svg
│ │ └── logo.png
│ └── tsconfig.json
├── LICENSE
├── NOTICE
├── README.md
├── samples
│ ├── mcp-integration-with-kb
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── assets
│ │ │ └── simplified-mcp-flow-diagram.png
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── chat_bedrock_st.py
│ │ └── uv.lock
│ ├── mcp-integration-with-nova-canvas
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── image_generator_st.py
│ │ └── uv.lock
│ ├── README.md
│ └── stepfunctions-tool-mcp-server
│ ├── README.md
│ └── sample_state_machines
│ ├── customer-create
│ │ └── app.py
│ ├── customer-id-from-email
│ │ └── app.py
│ ├── customer-info-from-id
│ │ └── app.py
│ └── template.yml
├── scripts
│ ├── README.md
│ └── verify_package_name.py
├── src
│ ├── amazon-bedrock-agentcore-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_bedrock_agentcore_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache.py
│ │ │ ├── doc_fetcher.py
│ │ │ ├── indexer.py
│ │ │ ├── text_processor.py
│ │ │ └── url_validator.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── SECURITY.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_config.py
│ │ │ ├── test_doc_fetcher.py
│ │ │ ├── test_indexer.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_text_processor.py
│ │ │ └── test_url_validator.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-kendra-index-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_kendra_index_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-keyspaces-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_keyspaces_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── services.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_analysis_service.py
│ │ │ ├── test_server.py
│ │ │ └── test_services.py
│ │ └── uv.lock
│ ├── amazon-mq-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_mq_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_mcp_generator.py
│ │ │ ├── consts.py
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── admin.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── doc
│ │ │ │ │ ├── rabbitmq_broker_sizing_guide.md
│ │ │ │ │ ├── rabbitmq_performance_optimization_best_practice.md
│ │ │ │ │ ├── rabbitmq_production_deployment_guidelines.md
│ │ │ │ │ ├── rabbitmq_quorum_queue_migration_guide.md
│ │ │ │ │ └── rabbitmq_setup_best_practice.md
│ │ │ │ ├── handlers.py
│ │ │ │ └── module.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── example
│ │ │ └── sample_mcp_q_cli.json
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_admin.py
│ │ │ │ ├── test_connection.py
│ │ │ │ ├── test_handlers.py
│ │ │ │ └── test_module.py
│ │ │ ├── test_aws_service_mcp_generator.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-neptune-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_neptune_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── exceptions.py
│ │ │ ├── graph_store
│ │ │ │ ├── __init__.py
│ │ │ │ ├── analytics.py
│ │ │ │ ├── base.py
│ │ │ │ └── database.py
│ │ │ ├── models.py
│ │ │ ├── neptune.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_analytics.py
│ │ │ ├── test_database.py
│ │ │ ├── test_exceptions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_neptune.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qbusiness-anonymous-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qbusiness_anonymous_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qindex-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qindex_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_clients.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── amazon-sns-sqs-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_sns_sqs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── consts.py
│ │ │ ├── generator.py
│ │ │ ├── server.py
│ │ │ ├── sns.py
│ │ │ └── sqs.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── print_tools.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_common.py
│ │ │ ├── test_generator.py
│ │ │ ├── test_server.py
│ │ │ ├── test_sns.py
│ │ │ └── test_sqs.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aurora-dsql-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aurora_dsql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection_reuse.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_profile_option.py
│ │ │ ├── test_readonly_enforcement.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-api-mcp-server
│ │ ├── .gitattributes
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_api_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent_scripts
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── manager.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── registry
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── application-failure-troubleshooting.script.md
│ │ │ │ │ ├── cloudtral-mutli-region-setup.script.md
│ │ │ │ │ ├── create_amazon_aurora_db_cluster_with_instances.script.md
│ │ │ │ │ ├── lambda-timeout-debugging.script.md
│ │ │ │ │ ├── scripts_format.md
│ │ │ │ │ └── troubleshoot-permissions-with-cloudtrail-events.script.md
│ │ │ │ ├── aws
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── driver.py
│ │ │ │ │ ├── pagination.py
│ │ │ │ │ ├── regions.py
│ │ │ │ │ ├── service.py
│ │ │ │ │ └── services.py
│ │ │ │ ├── common
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── command_metadata.py
│ │ │ │ │ ├── command.py
│ │ │ │ │ ├── config.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_operations.py
│ │ │ │ │ ├── file_system_controls.py
│ │ │ │ │ ├── helpers.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── data
│ │ │ │ │ └── api_metadata.json
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── read_only_operations_list.py
│ │ │ │ ├── parser
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── custom_validators
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── botocore_param_validator.py
│ │ │ │ │ │ ├── ec2_validator.py
│ │ │ │ │ │ └── ssm_validator.py
│ │ │ │ │ ├── interpretation.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ └── parser.py
│ │ │ │ ├── py.typed
│ │ │ │ └── security
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_api_customization.json
│ │ │ │ └── policy.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ └── http_header_validation_middleware.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── DEPLOYMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── agent_scripts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_manager.py
│ │ │ │ └── test_registry
│ │ │ │ ├── another_valid_script.script.md
│ │ │ │ ├── test_script.script.md
│ │ │ │ └── valid_script.script.md
│ │ │ ├── aws
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_driver.py
│ │ │ │ ├── test_pagination.py
│ │ │ │ ├── test_service.py
│ │ │ │ └── test_services.py
│ │ │ ├── common
│ │ │ │ ├── test_command.py
│ │ │ │ ├── test_config.py
│ │ │ │ ├── test_file_operations.py
│ │ │ │ ├── test_file_system_controls.py
│ │ │ │ ├── test_file_validation.py
│ │ │ │ └── test_helpers.py
│ │ │ ├── fixtures.py
│ │ │ ├── history_handler.py
│ │ │ ├── metadata
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_read_only_operations_list.py
│ │ │ ├── middleware
│ │ │ │ └── test_http_header_validation_middleware.py
│ │ │ ├── parser
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_file_path_detection.py
│ │ │ │ ├── test_lexer.py
│ │ │ │ ├── test_parser_customizations.py
│ │ │ │ └── test_parser.py
│ │ │ ├── test_security_policy.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-appsync-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_appsync_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── decorators.py
│ │ │ ├── helpers.py
│ │ │ ├── operations
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ └── validators.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_all_create_tools_write_protection.py
│ │ │ ├── test_create_api_cache.py
│ │ │ ├── test_create_api_key.py
│ │ │ ├── test_create_api.py
│ │ │ ├── test_create_channel_namespace.py
│ │ │ ├── test_create_datasource_tool.py
│ │ │ ├── test_create_datasource.py
│ │ │ ├── test_create_domain_name.py
│ │ │ ├── test_create_function.py
│ │ │ ├── test_create_graphql_api.py
│ │ │ ├── test_create_resolver.py
│ │ │ ├── test_create_schema_tool.py
│ │ │ ├── test_create_schema.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validators.py
│ │ │ └── test_write_operation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-custom-model-import-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_custom_model_import_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── prompts.py
│ │ │ ├── server.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── imported_model_service.py
│ │ │ │ └── model_import_service.py
│ │ │ ├── tools
│ │ │ │ ├── create_model_import_job.py
│ │ │ │ ├── delete_imported_model.py
│ │ │ │ ├── get_imported_model.py
│ │ │ │ ├── get_model_import_job.py
│ │ │ │ ├── list_imported_models.py
│ │ │ │ └── list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ └── matching.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── services
│ │ │ │ ├── test_imported_model_service.py
│ │ │ │ └── test_model_import_service.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_llm_context.py
│ │ │ ├── test_prompts.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── test_create_model_import_job.py
│ │ │ │ ├── test_delete_imported_model.py
│ │ │ │ ├── test_get_imported_model.py
│ │ │ │ ├── test_get_model_import_job.py
│ │ │ │ ├── test_list_imported_models.py
│ │ │ │ └── test_list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── test_aws.py
│ │ │ ├── test_config.py
│ │ │ └── test_matching.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-data-automation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_data_automation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── helpers.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-dataprocessing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_dataprocessing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── data_catalog_database_manager.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ └── data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── athena_data_catalog_handler.py
│ │ │ │ │ ├── athena_query_handler.py
│ │ │ │ │ └── athena_workgroup_handler.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── emr_ec2_cluster_handler.py
│ │ │ │ │ ├── emr_ec2_instance_handler.py
│ │ │ │ │ └── emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── crawler_handler.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ ├── glue_commons_handler.py
│ │ │ │ ├── glue_etl_handler.py
│ │ │ │ ├── interactive_sessions_handler.py
│ │ │ │ └── worklows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena_models.py
│ │ │ │ ├── common_resource_models.py
│ │ │ │ ├── data_catalog_models.py
│ │ │ │ ├── emr_models.py
│ │ │ │ └── glue_models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── consts.py
│ │ │ ├── logging_helper.py
│ │ │ └── sql_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_data_catalog_database_manager.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ └── test_data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_athena_data_catalog_handler.py
│ │ │ │ │ ├── test_athena_query_handler.py
│ │ │ │ │ ├── test_athena_workgroup_handler.py
│ │ │ │ │ └── test_custom_tags_athena.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── test_common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_custom_tags_emr.py
│ │ │ │ │ ├── test_emr_ec2_cluster_handler.py
│ │ │ │ │ ├── test_emr_ec2_instance_handler.py
│ │ │ │ │ └── test_emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_crawler_handler.py
│ │ │ │ ├── test_custom_tags_glue.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ ├── test_glue_commons_handler.py
│ │ │ │ ├── test_glue_etl_handler.py
│ │ │ │ ├── test_glue_interactive_sessions_handler.py
│ │ │ │ └── test_glue_workflows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_athena_models.py
│ │ │ │ ├── test_common_resource_models.py
│ │ │ │ ├── test_data_catalog_models.py
│ │ │ │ ├── test_emr_models.py
│ │ │ │ ├── test_glue_models.py
│ │ │ │ ├── test_interactive_sessions_models.py
│ │ │ │ └── test_workflows_models.py
│ │ │ ├── test_init.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_custom_tags.py
│ │ │ ├── test_logging_helper.py
│ │ │ └── test_sql_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-diagram-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_diagram_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── diagrams_tools.py
│ │ │ ├── models.py
│ │ │ ├── scanner.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ └── example_diagrams
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_example.py
│ │ │ │ ├── flow_example.py
│ │ │ │ └── sequence_example.py
│ │ │ ├── test_diagrams.py
│ │ │ ├── test_models.py
│ │ │ ├── test_sarif_fix.py
│ │ │ ├── test_scanner.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-documentation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_documentation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── server_aws_cn.py
│ │ │ ├── server_aws.py
│ │ │ ├── server_utils.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── basic-usage.gif
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── constants.py
│ │ │ ├── resources
│ │ │ │ └── lambda_sns_raw.html
│ │ │ ├── test_aws_cn_get_available_services_live.py
│ │ │ ├── test_aws_cn_read_documentation_live.py
│ │ │ ├── test_aws_read_documentation_live.py
│ │ │ ├── test_aws_recommend_live.py
│ │ │ ├── test_aws_search_live.py
│ │ │ ├── test_integ_basic.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
│ │ │ │ ├── __init__.py
│ │ │ │ ├── core.py
│ │ │ │ ├── s3.py
│ │ │ │ └── search.py
│ │ │ ├── search
│ │ │ │ ├── __init__.py
│ │ │ │ ├── file_association_engine.py
│ │ │ │ ├── file_type_detector.py
│ │ │ │ ├── genomics_search_orchestrator.py
│ │ │ │ ├── healthomics_search_engine.py
│ │ │ │ ├── json_response_builder.py
│ │ │ │ ├── pattern_matcher.py
│ │ │ │ ├── result_ranker.py
│ │ │ │ ├── s3_search_engine.py
│ │ │ │ └── scoring_engine.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── genomics_file_search.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
│ │ │ ├── search_config.py
│ │ │ └── validation_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── docs
│ │ │ └── workflow_linting.md
│ │ ├── LICENSE
│ │ ├── MCP_INSPECTOR_SETUP.md
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── fixtures
│ │ │ │ └── genomics_test_data.py
│ │ │ ├── INTEGRATION_TESTS_README.md
│ │ │ ├── QUICK_REFERENCE.md
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_file_association_engine.py
│ │ │ ├── test_file_type_detector.py
│ │ │ ├── test_genomics_file_search_integration_working.py
│ │ │ ├── test_genomics_search_orchestrator.py
│ │ │ ├── test_healthomics_search_engine.py
│ │ │ ├── test_helper_tools.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_integration_framework.py
│ │ │ ├── test_json_response_builder.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_pagination.py
│ │ │ ├── test_pattern_matcher.py
│ │ │ ├── test_performance_comparison.py
│ │ │ ├── test_result_ranker.py
│ │ │ ├── test_run_analysis.py
│ │ │ ├── test_s3_file_model.py
│ │ │ ├── test_s3_search_engine.py
│ │ │ ├── test_s3_utils.py
│ │ │ ├── test_scoring_engine.py
│ │ │ ├── test_search_config.py
│ │ │ ├── test_server.py
│ │ │ ├── test_troubleshooting.py
│ │ │ ├── test_validation_utils.py
│ │ │ ├── test_workflow_analysis.py
│ │ │ ├── test_workflow_execution.py
│ │ │ ├── test_workflow_linting.py
│ │ │ ├── test_workflow_management.py
│ │ │ ├── test_workflow_tools.py
│ │ │ └── TESTING_FRAMEWORK.md
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-iot-sitewise-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_iot_sitewise_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── models
│ │ │ │ ├── computation_data_models.py
│ │ │ │ └── metadata_transfer_data_models.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── anomaly_detection_workflow.py
│ │ │ │ ├── asset_hierarchy.py
│ │ │ │ ├── bulk_import_workflow.py
│ │ │ │ ├── data_exploration.py
│ │ │ │ └── data_ingestion.py
│ │ │ ├── server.py
│ │ │ ├── tool_metadata.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── sitewise_access.py
│ │ │ │ ├── sitewise_asset_models.py
│ │ │ │ ├── sitewise_assets.py
│ │ │ │ ├── sitewise_computation_models.py
│ │ │ │ ├── sitewise_data.py
│ │ │ │ ├── sitewise_executions.py
│ │ │ │ ├── sitewise_gateways.py
│ │ │ │ ├── sitewise_metadata_transfer.py
│ │ │ │ └── timestamp_tools.py
│ │ │ ├── validation_utils.py
│ │ │ └── validation.py
│ │ ├── CHANGELOG.md
│ │ ├── DEVELOPMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ └── wind_farm_example.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_server.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── models
│ │ │ │ ├── test_computation_data_models.py
│ │ │ │ └── test_metadata_transfer_data_models.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validation_utils.py
│ │ │ ├── test_validation.py
│ │ │ └── tools
│ │ │ ├── test_sitewise_access.py
│ │ │ ├── test_sitewise_asset_models.py
│ │ │ ├── test_sitewise_assets.py
│ │ │ ├── test_sitewise_computation_models.py
│ │ │ ├── test_sitewise_data.py
│ │ │ ├── test_sitewise_executions.py
│ │ │ ├── test_sitewise_gateways.py
│ │ │ ├── test_sitewise_metadata_transfer.py
│ │ │ └── test_timestamp_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-knowledge-mcp-server
│ │ └── README.md
│ ├── aws-location-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_location_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_server_integration.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-msk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_msk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── common_functions
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client_manager.py
│ │ │ │ └── common_functions.py
│ │ │ ├── logs_and_telemetry
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cluster_metrics_tools.py
│ │ │ │ ├── list_customer_iam_access.py
│ │ │ │ └── metric_config.py
│ │ │ ├── mutate_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_associate_scram_secret.py
│ │ │ │ ├── batch_disassociate_scram_secret.py
│ │ │ │ ├── create_cluster_v2.py
│ │ │ │ ├── put_cluster_policy.py
│ │ │ │ ├── reboot_broker.py
│ │ │ │ ├── update_broker_count.py
│ │ │ │ ├── update_broker_storage.py
│ │ │ │ ├── update_broker_type.py
│ │ │ │ ├── update_cluster_configuration.py
│ │ │ │ ├── update_monitoring.py
│ │ │ │ └── update_security.py
│ │ │ ├── mutate_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_configuration.py
│ │ │ │ ├── tag_resource.py
│ │ │ │ ├── untag_resource.py
│ │ │ │ └── update_configuration.py
│ │ │ ├── mutate_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_vpc_connection.py
│ │ │ │ ├── delete_vpc_connection.py
│ │ │ │ └── reject_client_vpc_connection.py
│ │ │ ├── read_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_cluster_operation.py
│ │ │ │ ├── describe_cluster.py
│ │ │ │ ├── get_bootstrap_brokers.py
│ │ │ │ ├── get_cluster_policy.py
│ │ │ │ ├── get_compatible_kafka_versions.py
│ │ │ │ ├── list_client_vpc_connections.py
│ │ │ │ ├── list_cluster_operations.py
│ │ │ │ ├── list_nodes.py
│ │ │ │ └── list_scram_secrets.py
│ │ │ ├── read_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_configuration_revision.py
│ │ │ │ ├── describe_configuration.py
│ │ │ │ ├── list_configuration_revisions.py
│ │ │ │ └── list_tags_for_resource.py
│ │ │ ├── read_global
│ │ │ │ ├── __init__.py
│ │ │ │ ├── list_clusters.py
│ │ │ │ ├── list_configurations.py
│ │ │ │ ├── list_kafka_versions.py
│ │ │ │ └── list_vpc_connections.py
│ │ │ ├── read_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ └── describe_vpc_connection.py
│ │ │ └── static_tools
│ │ │ ├── __init__.py
│ │ │ └── cluster_best_practices.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_client_manager.py
│ │ │ ├── test_cluster_metrics_tools.py
│ │ │ ├── test_common_functions.py
│ │ │ ├── test_create_cluster_v2.py
│ │ │ ├── test_create_configuration.py
│ │ │ ├── test_create_vpc_connection.py
│ │ │ ├── test_delete_vpc_connection.py
│ │ │ ├── test_describe_cluster_operation.py
│ │ │ ├── test_describe_cluster.py
│ │ │ ├── test_describe_configuration_revision.py
│ │ │ ├── test_describe_configuration.py
│ │ │ ├── test_describe_vpc_connection.py
│ │ │ ├── test_get_bootstrap_brokers.py
│ │ │ ├── test_get_cluster_policy.py
│ │ │ ├── test_get_compatible_kafka_versions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_list_client_vpc_connections.py
│ │ │ ├── test_list_cluster_operations.py
│ │ │ ├── test_list_clusters.py
│ │ │ ├── test_list_configuration_revisions.py
│ │ │ ├── test_list_configurations.py
│ │ │ ├── test_list_customer_iam_access.py
│ │ │ ├── test_list_kafka_versions.py
│ │ │ ├── test_list_nodes.py
│ │ │ ├── test_list_scram_secrets.py
│ │ │ ├── test_list_tags_for_resource.py
│ │ │ ├── test_list_vpc_connections.py
│ │ │ ├── test_logs_and_telemetry.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mutate_cluster_init.py
│ │ │ ├── test_mutate_cluster_success_cases.py
│ │ │ ├── test_mutate_cluster.py
│ │ │ ├── test_mutate_config_init.py
│ │ │ ├── test_mutate_vpc_init.py
│ │ │ ├── test_read_cluster_init_updated.py
│ │ │ ├── test_read_cluster_init.py
│ │ │ ├── test_read_config_init.py
│ │ │ ├── test_read_global_init.py
│ │ │ ├── test_read_vpc_init.py
│ │ │ ├── test_reject_client_vpc_connection.py
│ │ │ ├── test_server.py
│ │ │ ├── test_static_tools_init.py
│ │ │ ├── test_tag_resource.py
│ │ │ ├── test_tool_descriptions.py
│ │ │ ├── test_untag_resource.py
│ │ │ └── test_update_configuration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-pricing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_pricing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cdk_analyzer.py
│ │ │ ├── consts.py
│ │ │ ├── helpers.py
│ │ │ ├── models.py
│ │ │ ├── pricing_client.py
│ │ │ ├── pricing_transformer.py
│ │ │ ├── report_generator.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ ├── __init__.py
│ │ │ │ ├── COST_REPORT_TEMPLATE.md
│ │ │ │ └── patterns
│ │ │ │ ├── __init__.py
│ │ │ │ └── BEDROCK.md
│ │ │ └── terraform_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cdk_analyzer.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_pricing_client.py
│ │ │ ├── test_pricing_transformer.py
│ │ │ ├── test_report_generator.py
│ │ │ ├── test_server.py
│ │ │ └── test_terraform_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-serverless-mcp-server
│ │ ├── .pre-commit.config.yaml
│ │ ├── .python-version
│ │ ├── .secrets.baseline
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_serverless_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deployment_details.py
│ │ │ │ ├── deployment_list.py
│ │ │ │ ├── template_details.py
│ │ │ │ └── template_list.py
│ │ │ ├── server.py
│ │ │ ├── template
│ │ │ │ ├── __init__.py
│ │ │ │ ├── registry.py
│ │ │ │ ├── renderer.py
│ │ │ │ └── templates
│ │ │ │ ├── backend.j2
│ │ │ │ ├── frontend.j2
│ │ │ │ ├── fullstack.j2
│ │ │ │ └── README.md
│ │ │ ├── templates
│ │ │ │ ├── __init__.py
│ │ │ │ └── iam_policies.py
│ │ │ ├── tools
│ │ │ │ ├── common
│ │ │ │ │ └── base_tool.py
│ │ │ │ ├── esm
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── esm_diagnosis.py
│ │ │ │ │ ├── esm_guidance.py
│ │ │ │ │ ├── esm_recommend.py
│ │ │ │ │ └── secure_esm_guidance.py
│ │ │ │ ├── guidance
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── deploy_serverless_app_help.py
│ │ │ │ │ ├── get_iac_guidance.py
│ │ │ │ │ ├── get_lambda_event_schemas.py
│ │ │ │ │ ├── get_lambda_guidance.py
│ │ │ │ │ └── get_serverless_templates.py
│ │ │ │ ├── poller
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── esm_diagnosis.py
│ │ │ │ │ ├── esm_guidance.py
│ │ │ │ │ └── esm_recommend.py
│ │ │ │ ├── sam
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── sam_build.py
│ │ │ │ │ ├── sam_deploy.py
│ │ │ │ │ ├── sam_init.py
│ │ │ │ │ ├── sam_local_invoke.py
│ │ │ │ │ └── sam_logs.py
│ │ │ │ ├── schemas
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── describe_schema.py
│ │ │ │ │ ├── list_registries.py
│ │ │ │ │ └── search_schema.py
│ │ │ │ └── webapps
│ │ │ │ ├── __init__.py
│ │ │ │ ├── configure_domain.py
│ │ │ │ ├── deploy_webapp.py
│ │ │ │ ├── get_metrics.py
│ │ │ │ ├── update_webapp_frontend.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── deploy_service.py
│ │ │ │ │ ├── frontend_uploader.py
│ │ │ │ │ └── startup_script_generator.py
│ │ │ │ └── webapp_deployment_help.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_client_helper.py
│ │ │ ├── cloudformation.py
│ │ │ ├── const.py
│ │ │ ├── data_scrubber.py
│ │ │ ├── deployment_manager.py
│ │ │ ├── github.py
│ │ │ └── process.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_cloudformation.py
│ │ │ ├── test_configure_domain.py
│ │ │ ├── test_data_scrubber.py
│ │ │ ├── test_deploy_serverless_app_help.py
│ │ │ ├── test_deploy_service.py
│ │ │ ├── test_deploy_webapp.py
│ │ │ ├── test_deployment_details.py
│ │ │ ├── test_deployment_help.py
│ │ │ ├── test_deployment_list.py
│ │ │ ├── test_deployment_manager.py
│ │ │ ├── test_esm_diagnosis.py
│ │ │ ├── test_esm_guidance.py
│ │ │ ├── test_esm_recommend.py
│ │ │ ├── test_frontend_uploader.py
│ │ │ ├── test_get_iac_guidance.py
│ │ │ ├── test_get_lambda_event_schemas.py
│ │ │ ├── test_get_lambda_guidance.py
│ │ │ ├── test_get_metrics.py
│ │ │ ├── test_get_serverless_templates.py
│ │ │ ├── test_github.py
│ │ │ ├── test_iam_policies.py
│ │ │ ├── test_models.py
│ │ │ ├── test_process.py
│ │ │ ├── test_sam_build.py
│ │ │ ├── test_sam_deploy.py
│ │ │ ├── test_sam_init.py
│ │ │ ├── test_sam_local_invoke.py
│ │ │ ├── test_sam_logs.py
│ │ │ ├── test_schemas.py
│ │ │ ├── test_secure_esm_guidance.py
│ │ │ ├── test_server.py
│ │ │ ├── test_startup_script_generator.py
│ │ │ ├── test_template_details.py
│ │ │ ├── test_template_list.py
│ │ │ ├── test_template_registry.py
│ │ │ ├── test_template_renderer.py
│ │ │ └── test_update_webapp_frontend.py
│ │ └── uv.lock
│ ├── aws-support-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_support_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── consts.py
│ │ │ ├── debug_helper.py
│ │ │ ├── errors.py
│ │ │ ├── formatters.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftests.py
│ │ │ ├── test_aws_support_mcp_server.py
│ │ │ └── test_models.py
│ │ └── uv.lock
│ ├── bedrock-kb-retrieval-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── bedrock_kb_retrieval_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── knowledgebases
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clients.py
│ │ │ │ ├── discovery.py
│ │ │ │ └── retrieval.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_clients.py
│ │ │ ├── test_discovery.py
│ │ │ ├── test_env_config.py
│ │ │ ├── test_models.py
│ │ │ ├── test_retrieval.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── billing-cost-management-mcp-server
│ │ ├── __init__.py
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── billing_cost_management_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── decorator.py
│ │ │ │ ├── graviton_migration.py
│ │ │ │ ├── README.md
│ │ │ │ ├── savings_plans.py
│ │ │ │ └── types.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ └── recommendation_templates
│ │ │ │ ├── ebs_volume.template
│ │ │ │ ├── ec2_asg.template
│ │ │ │ ├── ec2_instance.template
│ │ │ │ ├── ecs_service.template
│ │ │ │ ├── idle.template
│ │ │ │ ├── lambda_function.template
│ │ │ │ ├── rds_database.template
│ │ │ │ ├── reserved_instances.template
│ │ │ │ └── savings_plans.template
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_pricing_operations.py
│ │ │ │ ├── aws_pricing_tools.py
│ │ │ │ ├── bcm_pricing_calculator_tools.py
│ │ │ │ ├── budget_tools.py
│ │ │ │ ├── compute_optimizer_tools.py
│ │ │ │ ├── cost_anomaly_tools.py
│ │ │ │ ├── cost_comparison_tools.py
│ │ │ │ ├── cost_explorer_operations.py
│ │ │ │ ├── cost_explorer_tools.py
│ │ │ │ ├── cost_optimization_hub_helpers.py
│ │ │ │ ├── cost_optimization_hub_tools.py
│ │ │ │ ├── free_tier_usage_tools.py
│ │ │ │ ├── recommendation_details_tools.py
│ │ │ │ ├── ri_performance_tools.py
│ │ │ │ ├── sp_performance_tools.py
│ │ │ │ ├── storage_lens_tools.py
│ │ │ │ └── unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_base.py
│ │ │ ├── constants.py
│ │ │ ├── logging_utils.py
│ │ │ └── sql_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── requirements.txt
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_prompts.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── fixtures.py
│ │ │ │ ├── test_aws_bcm_pricing_calculator_tools.py
│ │ │ │ ├── test_aws_pricing_tools.py
│ │ │ │ ├── test_budget_tools.py
│ │ │ │ ├── test_compute_optimizer_tools.py
│ │ │ │ ├── test_cost_anomaly_tools_enhanced.py
│ │ │ │ ├── test_cost_anomaly_tools.py
│ │ │ │ ├── test_cost_comparison_tools.py
│ │ │ │ ├── test_cost_explorer_operations.py
│ │ │ │ ├── test_cost_explorer_tools.py
│ │ │ │ ├── test_cost_optimization_hub_helpers.py
│ │ │ │ ├── test_cost_optimization_hub_tools.py
│ │ │ │ ├── test_free_tier_usage_tools_new.py
│ │ │ │ ├── test_recommendation_details_tools.py
│ │ │ │ ├── test_ri_performance_tools.py
│ │ │ │ ├── test_sp_performance_tools.py
│ │ │ │ ├── test_storage_lens_tools.py
│ │ │ │ └── test_unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── test_aws_service_base.py
│ │ │ └── test_sql_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ccapi-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ccapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── impl
│ │ │ │ ├── __init__.py
│ │ │ │ ├── tools
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── explanation.py
│ │ │ │ │ ├── infrastructure_generation.py
│ │ │ │ │ ├── resource_operations.py
│ │ │ │ │ ├── security_scanning.py
│ │ │ │ │ └── session_management.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ └── validation.py
│ │ │ ├── infrastructure_generator.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── schema_manager.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ └── __init__.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_checkov_install.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_explanation.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_infrastructure_generation.py
│ │ │ ├── test_infrastructure_generator.py
│ │ │ ├── test_models.py
│ │ │ ├── test_resource_operations.py
│ │ │ ├── test_schema_manager.py
│ │ │ ├── test_security_scanning.py
│ │ │ ├── test_server.py
│ │ │ ├── test_session_management.py
│ │ │ └── test_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cdk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cdk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── resources.py
│ │ │ │ ├── search_utils.py
│ │ │ │ ├── server.py
│ │ │ │ └── tools.py
│ │ │ ├── data
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cdk_nag_parser.py
│ │ │ │ ├── construct_descriptions.py
│ │ │ │ ├── genai_cdk_loader.py
│ │ │ │ ├── lambda_layer_parser.py
│ │ │ │ ├── lambda_powertools_loader.py
│ │ │ │ ├── schema_generator.py
│ │ │ │ └── solutions_constructs_parser.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── CDK_GENERAL_GUIDANCE.md
│ │ │ ├── CDK_NAG_GUIDANCE.md
│ │ │ └── lambda_powertools
│ │ │ ├── bedrock.md
│ │ │ ├── cdk.md
│ │ │ ├── dependencies.md
│ │ │ ├── index.md
│ │ │ ├── insights.md
│ │ │ ├── logging.md
│ │ │ ├── metrics.md
│ │ │ └── tracing.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── test_resources_enhanced.py
│ │ │ │ ├── test_resources.py
│ │ │ │ ├── test_search_utils.py
│ │ │ │ ├── test_server.py
│ │ │ │ └── test_tools.py
│ │ │ └── data
│ │ │ ├── test_cdk_nag_parser.py
│ │ │ ├── test_genai_cdk_loader.py
│ │ │ ├── test_lambda_powertools_loader.py
│ │ │ ├── test_schema_generator.py
│ │ │ └── test_solutions_constructs_parser.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cfn-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cfn_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── schema_manager.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_schema_manager.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudtrail-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudtrail_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── tools.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-applicationsignals-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_applicationsignals_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── audit_presentation_utils.py
│ │ │ ├── audit_utils.py
│ │ │ ├── aws_clients.py
│ │ │ ├── canary_utils.py
│ │ │ ├── enablement_guides
│ │ │ │ └── templates
│ │ │ │ └── ec2
│ │ │ │ └── ec2-python-enablement.md
│ │ │ ├── enablement_tools.py
│ │ │ ├── server.py
│ │ │ ├── service_audit_utils.py
│ │ │ ├── service_tools.py
│ │ │ ├── sli_report_client.py
│ │ │ ├── slo_tools.py
│ │ │ ├── trace_tools.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── evals
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── captor.py
│ │ │ │ ├── conversation_runner.py
│ │ │ │ ├── eval_config.py
│ │ │ │ ├── eval_mcp_server_wrapper.py
│ │ │ │ ├── eval_runner.py
│ │ │ │ ├── file_tools.py
│ │ │ │ ├── llm_provider.py
│ │ │ │ ├── mcp_client.py
│ │ │ │ ├── mcp_dependency_mocking_handler.py
│ │ │ │ ├── metrics_tracker.py
│ │ │ │ ├── mock_config_path_normalizer.py
│ │ │ │ ├── process_executor.py
│ │ │ │ ├── task_result.py
│ │ │ │ ├── task.py
│ │ │ │ ├── validation_prompts.py
│ │ │ │ └── validator.py
│ │ │ ├── README.md
│ │ │ ├── requirements.txt
│ │ │ └── tasks
│ │ │ ├── __init__.py
│ │ │ └── applicationsignals
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── get_enablement_guide
│ │ │ │ ├── __init__.py
│ │ │ │ └── enablement_tasks.py
│ │ │ └── investigations
│ │ │ ├── __init__.py
│ │ │ ├── fixtures
│ │ │ │ ├── bug-4-list-audit-findings-all-services-all-auditors.json
│ │ │ │ ├── bug-4-list-audit-findings-all-services-default-auditors.json
│ │ │ │ ├── bug-4-list-audit-findings-document-service-and-all-auditors.json
│ │ │ │ └── bug-4-list-services.json
│ │ │ └── investigation_tasks.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_audit_presentation_utils.py
│ │ │ ├── test_audit_utils.py
│ │ │ ├── test_aws_profile.py
│ │ │ ├── test_canary_utils.py
│ │ │ ├── test_enablement_tools.py
│ │ │ ├── test_initialization.py
│ │ │ ├── test_server_audit_functions.py
│ │ │ ├── test_server_audit_tools.py
│ │ │ ├── test_server.py
│ │ │ ├── test_service_audit_utils.py
│ │ │ ├── test_service_tools_operations.py
│ │ │ ├── test_sli_report_client.py
│ │ │ ├── test_slo_tools.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-appsignals-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_appsignals_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── audit_presentation_utils.py
│ │ │ ├── audit_utils.py
│ │ │ ├── aws_clients.py
│ │ │ ├── canary_utils.py
│ │ │ ├── enablement_guides
│ │ │ │ └── templates
│ │ │ │ └── ec2
│ │ │ │ └── ec2-python-enablement.md
│ │ │ ├── enablement_tools.py
│ │ │ ├── server.py
│ │ │ ├── service_audit_utils.py
│ │ │ ├── service_tools.py
│ │ │ ├── sli_report_client.py
│ │ │ ├── slo_tools.py
│ │ │ ├── trace_tools.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_audit_presentation_utils.py
│ │ │ ├── test_audit_utils.py
│ │ │ ├── test_aws_profile.py
│ │ │ ├── test_canary_utils.py
│ │ │ ├── test_enablement_tools.py
│ │ │ ├── test_initialization.py
│ │ │ ├── test_server_audit_functions.py
│ │ │ ├── test_server_audit_tools.py
│ │ │ ├── test_server.py
│ │ │ ├── test_service_audit_utils.py
│ │ │ ├── test_service_tools_operations.py
│ │ │ ├── test_sli_report_client.py
│ │ │ ├── test_slo_tools.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── cloudformation_template_generator.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── data
│ │ │ │ │ └── metric_metadata.json
│ │ │ │ ├── metric_analyzer.py
│ │ │ │ ├── metric_data_decomposer.py
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── common.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── test_active_alarms.py
│ │ │ │ ├── test_alarm_history_integration.py
│ │ │ │ ├── test_alarm_history.py
│ │ │ │ └── test_alarms_error_handling.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── test_logs_error_handling.py
│ │ │ │ ├── test_logs_models.py
│ │ │ │ └── test_logs_server.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── test_analyze_metric.py
│ │ │ │ ├── test_cloudformation_template_generator.py
│ │ │ │ ├── test_decomposer_trend.py
│ │ │ │ ├── test_metric_analyzer.py
│ │ │ │ ├── test_metrics_error_handling.py
│ │ │ │ ├── test_metrics_models.py
│ │ │ │ ├── test_metrics_server.py
│ │ │ │ ├── test_seasonal_detector.py
│ │ │ │ ├── test_seasonality_enum.py
│ │ │ │ ├── test_utils.py
│ │ │ │ └── test_validation_error.py
│ │ │ ├── test_common_and_server.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── code-doc-gen-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── code_doc_gen_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── doc_generator.py
│ │ │ ├── models.py
│ │ │ ├── repomix_manager.py
│ │ │ └── templates.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_doc_generator_edge_cases.py
│ │ │ ├── test_doc_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_repomix_manager_scenarios.py
│ │ │ ├── test_repomix_manager.py
│ │ │ ├── test_repomix_statistics.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server.py
│ │ │ └── test_templates.py
│ │ └── uv.lock
│ ├── core-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── core_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ └── PROMPT_UNDERSTANDING.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_response_types.py
│ │ │ ├── test_server.py
│ │ │ └── test_static.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cost-explorer-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cost_explorer_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── comparison_handler.py
│ │ │ ├── constants.py
│ │ │ ├── cost_usage_handler.py
│ │ │ ├── forecasting_handler.py
│ │ │ ├── helpers.py
│ │ │ ├── metadata_handler.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utility_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_comparison_handler.py
│ │ │ ├── test_cost_usage_handler.py
│ │ │ ├── test_forecasting_handler.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_metadata_handler.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_utility_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── document-loader-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ ├── document_loader_mcp_server
│ │ │ │ ├── __init__.py
│ │ │ │ └── server.py
│ │ │ └── py.typed
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_document_parsing.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── documentdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── documentdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── analytic_tools.py
│ │ │ ├── config.py
│ │ │ ├── connection_tools.py
│ │ │ ├── db_management_tools.py
│ │ │ ├── query_tools.py
│ │ │ ├── server.py
│ │ │ └── write_tools.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_analytic_tools.py
│ │ │ ├── test_connection_tools.py
│ │ │ ├── test_db_management_tools.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_tools.py
│ │ │ └── test_write_tools.py
│ │ └── uv.lock
│ ├── dynamodb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── dynamodb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── database_analysis_queries.py
│ │ │ ├── database_analyzers.py
│ │ │ ├── markdown_formatter.py
│ │ │ ├── prompts
│ │ │ │ └── dynamodb_architect.md
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── evals
│ │ │ │ ├── dynamic_evaluators.py
│ │ │ │ ├── evaluation_registry.py
│ │ │ │ ├── logging_config.py
│ │ │ │ ├── multiturn_evaluator.py
│ │ │ │ ├── README.md
│ │ │ │ ├── scenarios.py
│ │ │ │ └── test_dspy_evals.py
│ │ │ ├── test_dynamodb_server.py
│ │ │ ├── test_markdown_formatter.py
│ │ │ └── test_source_db_integration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ecs-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ecs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── ecs_troubleshooting.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ ├── status.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── detect_image_pull_failures.py
│ │ │ │ ├── fetch_cloudformation_status.py
│ │ │ │ ├── fetch_network_configuration.py
│ │ │ │ ├── fetch_service_events.py
│ │ │ │ ├── fetch_task_failures.py
│ │ │ │ ├── fetch_task_logs.py
│ │ │ │ ├── get_ecs_troubleshooting_guidance.py
│ │ │ │ └── utils.py
│ │ │ ├── main.py
│ │ │ ├── modules
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_knowledge_proxy.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── deployment_status.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ └── troubleshooting.py
│ │ │ ├── templates
│ │ │ │ ├── ecr_infrastructure.json
│ │ │ │ └── ecs_infrastructure.json
│ │ │ └── utils
│ │ │ ├── arn_parser.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── docker.py
│ │ │ ├── security.py
│ │ │ ├── templates.py
│ │ │ └── time_utils.py
│ │ ├── DEVELOPMENT.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── integ
│ │ │ │ └── mcp-inspector
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── run-tests.sh
│ │ │ │ └── scenarios
│ │ │ │ ├── 01_comprehensive_troubleshooting
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_cleanup.sh
│ │ │ │ │ ├── description.txt
│ │ │ │ │ └── utils
│ │ │ │ │ ├── mcp_helpers.sh
│ │ │ │ │ └── validation_helpers.sh
│ │ │ │ └── 02_test_knowledge_proxy_tools
│ │ │ │ ├── 01_create.sh
│ │ │ │ ├── 02_validate.sh
│ │ │ │ ├── 03_cleanup.sh
│ │ │ │ ├── description.txt
│ │ │ │ └── utils
│ │ │ │ ├── knowledge_validation_helpers.sh
│ │ │ │ └── mcp_knowledge_helpers.sh
│ │ │ ├── llm_testing
│ │ │ │ ├── invalid_cfn_template.yaml
│ │ │ │ ├── README.md
│ │ │ │ ├── run_tests.sh
│ │ │ │ ├── scenarios
│ │ │ │ │ ├── 01_cloudformation_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 02_service_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 03_task_exit_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 04_network_configuration_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 05_resource_constraint_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ └── 06_load_balancer_failure
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ └── description.txt
│ │ │ │ ├── SCRIPT_IMPROVEMENTS.md
│ │ │ │ └── utils
│ │ │ │ ├── aws_helpers.sh
│ │ │ │ └── evaluation_template.md
│ │ │ └── unit
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_delete_api.py
│ │ │ │ ├── test_ecs_troubleshooting.py
│ │ │ │ ├── test_resource_management_api.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ └── test_fetch_network_configuration.py
│ │ │ ├── conftest.py
│ │ │ ├── modules
│ │ │ │ ├── test_aws_knowledge_proxy.py
│ │ │ │ └── test_resource_management_module.py
│ │ │ ├── test_aws_role_utils.py
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_containerize.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_docker_utils.py
│ │ │ ├── test_docker_with_role.py
│ │ │ ├── test_image_pull_failure_extended.py
│ │ │ ├── test_image_pull_failure.py
│ │ │ ├── test_infrastructure_role.py
│ │ │ ├── test_infrastructure.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_main.py
│ │ │ ├── test_resource_management_api_operation.py
│ │ │ ├── test_resource_management_tool.py
│ │ │ ├── test_resource_management.py
│ │ │ ├── test_security_integration.py
│ │ │ ├── test_status_pytest.py
│ │ │ ├── test_status.py
│ │ │ ├── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_detect_image_pull_failures.py
│ │ │ │ ├── test_fetch_cloudformation_status.py
│ │ │ │ ├── test_fetch_service_events.py
│ │ │ │ ├── test_fetch_task_failures.py
│ │ │ │ ├── test_fetch_task_logs.py
│ │ │ │ ├── test_get_ecs_troubleshooting_guidance.py
│ │ │ │ ├── test_is_ecr_image_security.py
│ │ │ │ └── test_utils.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── async_test_utils.py
│ │ │ ├── test_arn_parser.py
│ │ │ ├── test_config.py
│ │ │ ├── test_docker.py
│ │ │ ├── test_response_sanitization.py
│ │ │ ├── test_security_extended.py
│ │ │ ├── test_security.py
│ │ │ ├── test_templates.py
│ │ │ └── test_time_utils.py
│ │ └── uv.lock
│ ├── eks-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── eks_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── cloudwatch_handler.py
│ │ │ ├── cloudwatch_metrics_guidance_handler.py
│ │ │ ├── consts.py
│ │ │ ├── data
│ │ │ │ └── eks_cloudwatch_metrics_guidance.json
│ │ │ ├── eks_kb_handler.py
│ │ │ ├── eks_stack_handler.py
│ │ │ ├── iam_handler.py
│ │ │ ├── insights_handler.py
│ │ │ ├── k8s_apis.py
│ │ │ ├── k8s_client_cache.py
│ │ │ ├── k8s_handler.py
│ │ │ ├── logging_helper.py
│ │ │ ├── models.py
│ │ │ ├── scripts
│ │ │ │ └── update_eks_cloudwatch_metrics_guidance.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ ├── eks-templates
│ │ │ │ │ └── eks-with-vpc.yaml
│ │ │ │ └── k8s-templates
│ │ │ │ ├── deployment.yaml
│ │ │ │ └── service.yaml
│ │ │ └── vpc_config_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_cloudwatch_handler.py
│ │ │ ├── test_cloudwatch_metrics_guidance_handler.py
│ │ │ ├── test_eks_kb_handler.py
│ │ │ ├── test_eks_stack_handler.py
│ │ │ ├── test_iam_handler.py
│ │ │ ├── test_init.py
│ │ │ ├── test_insights_handler.py
│ │ │ ├── test_k8s_apis.py
│ │ │ ├── test_k8s_client_cache.py
│ │ │ ├── test_k8s_handler.py
│ │ │ ├── test_logging_helper.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_vpc_config_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── elasticache-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── elasticache_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── decorators.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ └── processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_log_group.py
│ │ │ │ ├── describe_log_groups.py
│ │ │ │ ├── describe_log_streams.py
│ │ │ │ ├── filter_log_events.py
│ │ │ │ └── get_log_events.py
│ │ │ ├── firehose
│ │ │ │ ├── __init__.py
│ │ │ │ └── list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_apply_update_action.py
│ │ │ │ ├── batch_stop_update_action.py
│ │ │ │ ├── describe_cache_engine_versions.py
│ │ │ │ ├── describe_engine_default_parameters.py
│ │ │ │ ├── describe_events.py
│ │ │ │ └── describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── complete_migration.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ ├── processors.py
│ │ │ │ ├── start_migration.py
│ │ │ │ └── test_migration.py
│ │ │ └── serverless
│ │ │ ├── __init__.py
│ │ │ ├── connect.py
│ │ │ ├── create.py
│ │ │ ├── delete.py
│ │ │ ├── describe.py
│ │ │ ├── models.py
│ │ │ └── modify.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection.py
│ │ │ ├── test_decorators.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── tools
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create_additional.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ └── test_processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ └── test_get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_create_log_group.py
│ │ │ │ ├── test_describe_log_groups.py
│ │ │ │ ├── test_describe_log_streams.py
│ │ │ │ ├── test_filter_log_events.py
│ │ │ │ └── test_get_log_events.py
│ │ │ ├── firehose
│ │ │ │ └── test_list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_batch_apply_update_action.py
│ │ │ │ ├── test_batch_stop_update_action.py
│ │ │ │ ├── test_describe_cache_engine_versions.py
│ │ │ │ ├── test_describe_engine_default_parameters.py
│ │ │ │ ├── test_describe_events.py
│ │ │ │ └── test_describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_complete_migration.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_optional_fields.py
│ │ │ │ ├── test_connect_partial_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ ├── test_processors.py
│ │ │ │ ├── test_start_migration.py
│ │ │ │ └── test_test_migration.py
│ │ │ └── serverless
│ │ │ ├── test_connect_additional.py
│ │ │ ├── test_connect_coverage_additional.py
│ │ │ ├── test_connect_optional_fields.py
│ │ │ ├── test_connect.py
│ │ │ ├── test_create.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_describe.py
│ │ │ └── test_modify.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── finch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── finch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── build.py
│ │ │ ├── common.py
│ │ │ ├── ecr.py
│ │ │ ├── push.py
│ │ │ └── vm.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_cli_flags.py
│ │ │ ├── test_logging_configuration.py
│ │ │ ├── test_server.py
│ │ │ ├── test_utils_build.py
│ │ │ ├── test_utils_common.py
│ │ │ ├── test_utils_ecr.py
│ │ │ ├── test_utils_push.py
│ │ │ └── test_utils_vm.py
│ │ └── uv.lock
│ ├── frontend-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── frontend_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ └── react
│ │ │ │ ├── essential-knowledge.md
│ │ │ │ └── troubleshooting.md
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ └── file_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_file_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── git-repo-research-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── git_repo_research_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── defaults.py
│ │ │ ├── embeddings.py
│ │ │ ├── github_search.py
│ │ │ ├── indexer.py
│ │ │ ├── models.py
│ │ │ ├── repository.py
│ │ │ ├── search.py
│ │ │ ├── server.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_errors_repository.py
│ │ │ ├── test_github_search_edge_cases.py
│ │ │ ├── test_graphql_github_search.py
│ │ │ ├── test_local_repository.py
│ │ │ ├── test_repository_utils.py
│ │ │ ├── test_rest_github_search.py
│ │ │ ├── test_search.py
│ │ │ ├── test_server.py
│ │ │ └── test_url_repository.py
│ │ └── uv.lock
│ ├── healthlake-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── healthlake_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── fhir_operations.py
│ │ │ ├── main.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── mcp_config.json
│ │ │ └── README.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_fhir_client_comprehensive.py
│ │ │ ├── test_fhir_error_scenarios.py
│ │ │ ├── test_fhir_operations.py
│ │ │ ├── test_integration_mock_based.py
│ │ │ ├── test_main_edge_cases.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mcp_integration_coverage.py
│ │ │ ├── test_models_edge_cases.py
│ │ │ ├── test_models.py
│ │ │ ├── test_readonly_mode.py
│ │ │ ├── test_server_core.py
│ │ │ ├── test_server_error_handling.py
│ │ │ ├── test_server_mcp_handlers.py
│ │ │ ├── test_server_toolhandler.py
│ │ │ └── test_server_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── iam-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── iam_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── DESIGN_COMPLIANCE.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── get_policy_document_example.py
│ │ │ └── inline_policy_demo.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_inline_policies.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── lambda-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── lambda_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── README.md
│ │ │ └── sample_functions
│ │ │ ├── customer-create
│ │ │ │ └── app.py
│ │ │ ├── customer-id-from-email
│ │ │ │ └── app.py
│ │ │ ├── customer-info-from-id
│ │ │ │ └── app.py
│ │ │ └── template.yml
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_format_lambda_response.py
│ │ │ ├── test_integration_coverage.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_register_lambda_functions.py
│ │ │ ├── test_schema_integration.py
│ │ │ ├── test_server_coverage_additional.py
│ │ │ ├── test_server_coverage.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mcp-lambda-handler
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── mcp_lambda_handler
│ │ │ ├── __init__.py
│ │ │ ├── mcp_lambda_handler.py
│ │ │ ├── session.py
│ │ │ └── types.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_lambda_handler.py
│ │ └── uv.lock
│ ├── memcached-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── memcached_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ └── cache.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_cache_readonly.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mysql-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── mysql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── connection
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abstract_db_connection.py
│ │ │ │ ├── asyncmy_pool_connection.py
│ │ │ │ ├── db_connection_singleton.py
│ │ │ │ └── rds_data_api_connection.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_abstract_db_connection.py
│ │ │ ├── test_asyncmy_pool_connection.py
│ │ │ ├── test_db_connection_singleton.py
│ │ │ ├── test_rds_data_api_connection.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── nova-canvas-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── nova_canvas_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── novacanvas.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_novacanvas.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── openapi-mcp-server
│ │ ├── .coveragerc
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── AUTHENTICATION.md
│ │ ├── AWS_BEST_PRACTICES.md
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── openapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ └── config.py
│ │ │ ├── auth
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_key_auth.py
│ │ │ │ ├── auth_cache.py
│ │ │ │ ├── auth_errors.py
│ │ │ │ ├── auth_factory.py
│ │ │ │ ├── auth_protocol.py
│ │ │ │ ├── auth_provider.py
│ │ │ │ ├── base_auth.py
│ │ │ │ ├── basic_auth.py
│ │ │ │ ├── bearer_auth.py
│ │ │ │ ├── cognito_auth.py
│ │ │ │ └── register.py
│ │ │ ├── patch
│ │ │ │ └── __init__.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── generators
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── operation_prompts.py
│ │ │ │ │ └── workflow_prompts.py
│ │ │ │ ├── models.py
│ │ │ │ └── prompt_manager.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache_provider.py
│ │ │ ├── config.py
│ │ │ ├── error_handler.py
│ │ │ ├── http_client.py
│ │ │ ├── metrics_provider.py
│ │ │ ├── openapi_validator.py
│ │ │ └── openapi.py
│ │ ├── CHANGELOG.md
│ │ ├── DEPLOYMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── OBSERVABILITY.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── api
│ │ │ │ └── test_config.py
│ │ │ ├── auth
│ │ │ │ ├── test_api_key_auth.py
│ │ │ │ ├── test_auth_cache.py
│ │ │ │ ├── test_auth_errors.py
│ │ │ │ ├── test_auth_factory_caching.py
│ │ │ │ ├── test_auth_factory_coverage.py
│ │ │ │ ├── test_auth_factory.py
│ │ │ │ ├── test_auth_protocol_additional.py
│ │ │ │ ├── test_auth_protocol_boost.py
│ │ │ │ ├── test_auth_protocol_coverage.py
│ │ │ │ ├── test_auth_protocol_extended.py
│ │ │ │ ├── test_auth_protocol_improved.py
│ │ │ │ ├── test_auth_protocol.py
│ │ │ │ ├── test_auth_provider_additional.py
│ │ │ │ ├── test_base_auth_coverage.py
│ │ │ │ ├── test_base_auth.py
│ │ │ │ ├── test_basic_auth.py
│ │ │ │ ├── test_bearer_auth.py
│ │ │ │ ├── test_cognito_auth_additional_coverage.py
│ │ │ │ ├── test_cognito_auth_boost_coverage.py
│ │ │ │ ├── test_cognito_auth_client_credentials.py
│ │ │ │ ├── test_cognito_auth_coverage_boost.py
│ │ │ │ ├── test_cognito_auth_exceptions.py
│ │ │ │ ├── test_cognito_auth.py
│ │ │ │ ├── test_register_coverage.py
│ │ │ │ └── test_register.py
│ │ │ ├── prompts
│ │ │ │ ├── standalone
│ │ │ │ │ ├── test_operation_prompt.py
│ │ │ │ │ ├── test_prompt_arguments.py
│ │ │ │ │ └── test_secure_operation_prompt.py
│ │ │ │ ├── test_mcp_prompt_manager_integration.py
│ │ │ │ ├── test_mcp_prompt_manager.py
│ │ │ │ ├── test_models_dict_method.py
│ │ │ │ ├── test_operation_prompts_extended.py
│ │ │ │ ├── test_prompt_manager_additional.py
│ │ │ │ ├── test_prompt_manager_comprehensive.py
│ │ │ │ ├── test_prompt_manager_coverage.py
│ │ │ │ └── test_prompt_registration.py
│ │ │ ├── README.md
│ │ │ ├── test_api_name.py
│ │ │ ├── test_cache_coverage_89.py
│ │ │ ├── test_client.py
│ │ │ ├── test_coverage_boost.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main_extended.py
│ │ │ ├── test_main.py
│ │ │ ├── test_openapi_coverage_89.py
│ │ │ ├── test_server_auth_errors.py
│ │ │ ├── test_server_coverage_boost_2.py
│ │ │ ├── test_server_coverage_boost.py
│ │ │ ├── test_server_exception_handling.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server_httpx_version.py
│ │ │ ├── test_server_part1.py
│ │ │ ├── test_server_route_logging.py
│ │ │ ├── test_server_signal_handlers.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── test_cache_provider.py
│ │ │ ├── test_error_handler_boost.py
│ │ │ ├── test_error_handler_extended.py
│ │ │ ├── test_error_handler_fix.py
│ │ │ ├── test_error_handler.py
│ │ │ ├── test_http_client_comprehensive.py
│ │ │ ├── test_http_client_extended.py
│ │ │ ├── test_http_client_extended2.py
│ │ │ ├── test_http_client_import_error.py
│ │ │ ├── test_http_client.py
│ │ │ ├── test_metrics_provider_decorators.py
│ │ │ ├── test_metrics_provider_extended2.py
│ │ │ ├── test_metrics_provider_prometheus.py
│ │ │ ├── test_metrics_provider.py
│ │ │ ├── test_openapi_validator.py
│ │ │ └── test_openapi.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── postgres-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── postgres_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── connection
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abstract_db_connection.py
│ │ │ │ ├── db_connection_singleton.py
│ │ │ │ ├── psycopg_pool_connection.py
│ │ │ │ └── rds_api_connection.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_psycopg_connector.py
│ │ │ ├── test_server.py
│ │ │ └── test_singleton.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── prometheus-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── prometheus_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_aws_credentials.py
│ │ │ ├── test_config_manager.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_coverage_gaps.py
│ │ │ ├── test_coverage_improvement.py
│ │ │ ├── test_final_coverage.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_prometheus_client.py
│ │ │ ├── test_prometheus_connection.py
│ │ │ ├── test_security_validator.py
│ │ │ ├── test_server_coverage.py
│ │ │ ├── test_tools.py
│ │ │ └── test_workspace_config.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── redshift-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── redshift_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── redshift.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_redshift.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── s3-tables-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── s3_tables_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── database.py
│ │ │ ├── engines
│ │ │ │ ├── __init__.py
│ │ │ │ └── pyiceberg.py
│ │ │ ├── file_processor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── csv.py
│ │ │ │ ├── parquet.py
│ │ │ │ └── utils.py
│ │ │ ├── models.py
│ │ │ ├── namespaces.py
│ │ │ ├── resources.py
│ │ │ ├── s3_operations.py
│ │ │ ├── server.py
│ │ │ ├── table_buckets.py
│ │ │ ├── tables.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTEXT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_csv.py
│ │ │ ├── test_database.py
│ │ │ ├── test_file_processor_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_namespaces.py
│ │ │ ├── test_parquet.py
│ │ │ ├── test_pyiceberg.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_s3_operations.py
│ │ │ ├── test_server.py
│ │ │ ├── test_table_buckets.py
│ │ │ ├── test_tables.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── stepfunctions-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── stepfunctions_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_create_state_machine_tool.py
│ │ │ ├── test_filter_state_machines_by_tag.py
│ │ │ ├── test_format_state_machine_response.py
│ │ │ ├── test_get_schema_arn_from_state_machine_arn.py
│ │ │ ├── test_get_schema_from_registry.py
│ │ │ ├── test_invoke_express_state_machine_impl.py
│ │ │ ├── test_invoke_standard_state_machine_impl.py
│ │ │ ├── test_main.py
│ │ │ ├── test_register_state_machines.py
│ │ │ ├── test_sanitize_tool_name.py
│ │ │ ├── test_server.py
│ │ │ └── test_validate_state_machine_name.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── syntheticdata-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── syntheticdata_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── pandas_interpreter.py
│ │ │ ├── server.py
│ │ │ └── storage
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── loader.py
│ │ │ └── s3.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_constants.py
│ │ │ ├── test_pandas_interpreter.py
│ │ │ ├── test_server.py
│ │ │ └── test_storage
│ │ │ ├── __init__.py
│ │ │ ├── test_loader.py
│ │ │ └── test_s3.py
│ │ └── uv.lock
│ ├── terraform-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── terraform_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── impl
│ │ │ │ ├── resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── terraform_aws_provider_resources_listing.py
│ │ │ │ │ └── terraform_awscc_provider_resources_listing.py
│ │ │ │ └── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── execute_terraform_command.py
│ │ │ │ ├── execute_terragrunt_command.py
│ │ │ │ ├── run_checkov_scan.py
│ │ │ │ ├── search_aws_provider_docs.py
│ │ │ │ ├── search_awscc_provider_docs.py
│ │ │ │ ├── search_specific_aws_ia_modules.py
│ │ │ │ ├── search_user_provided_module.py
│ │ │ │ └── utils.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── scripts
│ │ │ │ ├── generate_aws_provider_resources.py
│ │ │ │ ├── generate_awscc_provider_resources.py
│ │ │ │ └── scrape_aws_terraform_best_practices.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── AWS_PROVIDER_RESOURCES.md
│ │ │ ├── AWS_TERRAFORM_BEST_PRACTICES.md
│ │ │ ├── AWSCC_PROVIDER_RESOURCES.md
│ │ │ ├── MCP_INSTRUCTIONS.md
│ │ │ └── TERRAFORM_WORKFLOW_GUIDE.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_command_impl.py
│ │ │ ├── test_execute_terraform_command.py
│ │ │ ├── test_execute_terragrunt_command.py
│ │ │ ├── test_models.py
│ │ │ ├── test_parameter_annotations.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_run_checkov_scan.py
│ │ │ ├── test_search_user_provided_module.py
│ │ │ ├── test_server.py
│ │ │ ├── test_tool_implementations.py
│ │ │ ├── test_utils_additional.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── timestream-for-influxdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── timestream_for_influxdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── valkey-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── valkey_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── bitmap.py
│ │ │ │ ├── hash.py
│ │ │ │ ├── hyperloglog.py
│ │ │ │ ├── json.py
│ │ │ │ ├── list.py
│ │ │ │ ├── misc.py
│ │ │ │ ├── server_management.py
│ │ │ │ ├── set.py
│ │ │ │ ├── sorted_set.py
│ │ │ │ ├── stream.py
│ │ │ │ └── string.py
│ │ │ └── version.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_bitmap.py
│ │ │ ├── test_config.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_hash.py
│ │ │ ├── test_hyperloglog.py
│ │ │ ├── test_init.py
│ │ │ ├── test_json_additional.py
│ │ │ ├── test_json_readonly.py
│ │ │ ├── test_json.py
│ │ │ ├── test_list_additional.py
│ │ │ ├── test_list_readonly.py
│ │ │ ├── test_list.py
│ │ │ ├── test_main.py
│ │ │ ├── test_misc.py
│ │ │ ├── test_server_management.py
│ │ │ ├── test_set_readonly.py
│ │ │ ├── test_set.py
│ │ │ ├── test_sorted_set_additional.py
│ │ │ ├── test_sorted_set_readonly.py
│ │ │ ├── test_sorted_set.py
│ │ │ ├── test_stream_additional.py
│ │ │ ├── test_stream_readonly.py
│ │ │ ├── test_stream.py
│ │ │ └── test_string.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ └── well-architected-security-mcp-server
│ ├── .python-version
│ ├── awslabs
│ │ └── well_architected_security_mcp_server
│ │ ├── __init__.py
│ │ ├── consts.py
│ │ ├── server.py
│ │ └── util
│ │ ├── __init__.py
│ │ ├── network_security.py
│ │ ├── prompt_utils.py
│ │ ├── resource_utils.py
│ │ ├── security_services.py
│ │ └── storage_security.py
│ ├── PROMPT_TEMPLATE.md
│ ├── pyproject.toml
│ ├── README.md
│ ├── tests
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── README.md
│ │ ├── test_access_analyzer_fix.py
│ │ ├── test_network_security_additional.py
│ │ ├── test_network_security.py
│ │ ├── test_prompt_utils_coverage.py
│ │ ├── test_prompt_utils.py
│ │ ├── test_resource_utils_fix.py
│ │ ├── test_resource_utils.py
│ │ ├── test_security_services_additional.py
│ │ ├── test_security_services_coverage.py
│ │ ├── test_security_services.py
│ │ ├── test_server_additional.py
│ │ ├── test_server_coverage.py
│ │ ├── test_server_prompts.py
│ │ ├── test_server_security_findings.py
│ │ ├── test_server.py
│ │ ├── test_storage_security_additional.py
│ │ ├── test_storage_security_comprehensive.py
│ │ ├── test_storage_security_edge_cases.py
│ │ ├── test_storage_security_recommendations.py
│ │ ├── test_storage_security.py
│ │ └── test_user_agent_config.py
│ └── uv.lock
├── testing
│ ├── __init__.py
│ ├── mcp_test_client.py
│ ├── mcp_test_runner.py
│ ├── pytest_utils.py
│ ├── README.md
│ └── types.py
└── VIBE_CODING_TIPS_TRICKS.md
```
# Files
--------------------------------------------------------------------------------
/src/aws-dataprocessing-mcp-server/tests/handlers/glue/test_glue_interactive_sessions_handler.py:
--------------------------------------------------------------------------------
```python
1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
4 | # with the License. A copy of the License is located at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
9 | # OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
10 | # and limitations under the License.
11 | # ruff: noqa: D101, D102, D103
12 | """Tests for the Glue Interactive Sessions handler."""
13 |
14 | import pytest
15 | from awslabs.aws_dataprocessing_mcp_server.handlers.glue.interactive_sessions_handler import (
16 | GlueInteractiveSessionsHandler,
17 | )
18 | from botocore.exceptions import ClientError
19 | from mcp.server.fastmcp import Context
20 | from unittest.mock import MagicMock, patch
21 |
22 |
23 | @pytest.mark.asyncio
24 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
25 | async def test_glue_interactive_sessions_handler_initialization(mock_create_client):
26 | # Create a mock Glue client
27 | mock_glue_client = MagicMock()
28 | mock_create_client.return_value = mock_glue_client
29 |
30 | # Create a mock MCP server
31 | mock_mcp = MagicMock()
32 |
33 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
34 | GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
35 |
36 | # Verify that create_boto3_client was called with 'glue'
37 | mock_create_client.assert_called_once_with('glue')
38 |
39 | # Verify that all tools were registered
40 | assert mock_mcp.tool.call_count == 2
41 |
42 | # Get all call args
43 | call_args_list = mock_mcp.tool.call_args_list
44 |
45 | # Get all tool names that were registered
46 | tool_names = [call_args[1]['name'] for call_args in call_args_list]
47 |
48 | # Verify that all expected tools were registered
49 | assert 'manage_aws_glue_sessions' in tool_names
50 | assert 'manage_aws_glue_statements' in tool_names
51 |
52 |
53 | # Tests for manage_aws_glue_sessions method
54 |
55 |
56 | @pytest.mark.asyncio
57 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
58 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.prepare_resource_tags')
59 | async def test_create_session_success(mock_prepare_tags, mock_create_client):
60 | # Create a mock Glue client
61 | mock_glue_client = MagicMock()
62 | mock_create_client.return_value = mock_glue_client
63 |
64 | # Mock the resource tags
65 | mock_prepare_tags.return_value = {'ManagedBy': 'MCP'}
66 |
67 | # Create a mock MCP server
68 | mock_mcp = MagicMock()
69 |
70 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
71 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
72 | handler.glue_client = mock_glue_client
73 |
74 | # Create a mock context
75 | mock_ctx = MagicMock(spec=Context)
76 |
77 | # Mock the create_session response
78 | mock_glue_client.create_session.return_value = {
79 | 'Session': {'Id': 'test-session', 'Status': 'PROVISIONING'}
80 | }
81 |
82 | # Call the manage_aws_glue_sessions method with create-session operation
83 | result = await handler.manage_aws_glue_sessions(
84 | mock_ctx,
85 | operation='create-session',
86 | session_id='test-session',
87 | role='arn:aws:iam::123456789012:role/GlueInteractiveSessionRole',
88 | command={'Name': 'glueetl', 'PythonVersion': '3'},
89 | glue_version='3.0',
90 | description='Test session',
91 | timeout=60,
92 | idle_timeout=30,
93 | default_arguments={'--enable-glue-datacatalog': 'true'},
94 | connections={'Connections': ['test-connection']},
95 | max_capacity=5.0,
96 | number_of_workers=2,
97 | worker_type='G.1X',
98 | security_configuration='test-security-config',
99 | tags={'Environment': 'Test'},
100 | )
101 |
102 | # Verify the result
103 | assert not result.isError
104 | assert len(result.content) == 1
105 | assert result.content[0].type == 'text'
106 | assert 'Successfully created session test-session' in result.content[0].text
107 | assert result.session_id == 'test-session'
108 | assert result.session['Status'] == 'PROVISIONING'
109 |
110 | # Verify that create_session was called with the correct parameters
111 | mock_glue_client.create_session.assert_called_once()
112 | args, kwargs = mock_glue_client.create_session.call_args
113 | assert kwargs['Id'] == 'test-session'
114 | assert kwargs['Role'] == 'arn:aws:iam::123456789012:role/GlueInteractiveSessionRole'
115 | assert kwargs['Command'] == {'Name': 'glueetl', 'PythonVersion': '3'}
116 | assert kwargs['GlueVersion'] == '3.0'
117 | assert kwargs['Description'] == 'Test session'
118 | assert kwargs['Timeout'] == 60
119 | assert kwargs['IdleTimeout'] == 30
120 | assert kwargs['DefaultArguments'] == {'--enable-glue-datacatalog': 'true'}
121 | assert kwargs['Connections'] == {'Connections': ['test-connection']}
122 | assert kwargs['MaxCapacity'] == 5.0
123 | assert kwargs['NumberOfWorkers'] == 2
124 | assert kwargs['WorkerType'] == 'G.1X'
125 | assert kwargs['SecurityConfiguration'] == 'test-security-config'
126 | assert 'Tags' in kwargs
127 | assert kwargs['Tags']['Environment'] == 'Test'
128 | assert kwargs['Tags']['ManagedBy'] == 'MCP'
129 |
130 |
131 | @pytest.mark.asyncio
132 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
133 | async def test_create_session_no_write_access(mock_create_client):
134 | # Create a mock Glue client
135 | mock_glue_client = MagicMock()
136 | mock_create_client.return_value = mock_glue_client
137 |
138 | # Create a mock MCP server
139 | mock_mcp = MagicMock()
140 |
141 | # Initialize the Glue Interactive Sessions handler with the mock MCP server without write access
142 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
143 | handler.glue_client = mock_glue_client
144 |
145 | # Create a mock context
146 | mock_ctx = MagicMock(spec=Context)
147 |
148 | # Call the manage_aws_glue_sessions method with create-session operation
149 | result = await handler.manage_aws_glue_sessions(
150 | mock_ctx,
151 | operation='create-session',
152 | session_id='test-session',
153 | role='arn:aws:iam::123456789012:role/GlueInteractiveSessionRole',
154 | command={'Name': 'glueetl', 'PythonVersion': '3'},
155 | )
156 |
157 | # Verify the result indicates an error due to no write access
158 | assert result.isError
159 | assert len(result.content) == 1
160 | assert result.content[0].type == 'text'
161 | assert 'Operation create-session is not allowed without write access' in result.content[0].text
162 | assert result.session_id == ''
163 |
164 | # Verify that create_session was NOT called
165 | mock_glue_client.create_session.assert_not_called()
166 |
167 |
168 | @pytest.mark.asyncio
169 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
170 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
171 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
172 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
173 | async def test_delete_session_success(
174 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
175 | ):
176 | # Create a mock Glue client
177 | mock_glue_client = MagicMock()
178 | mock_create_client.return_value = mock_glue_client
179 |
180 | # Mock the region and account ID
181 | mock_get_region.return_value = 'us-east-1'
182 | mock_get_account_id.return_value = '123456789012'
183 |
184 | # Mock the is_resource_mcp_managed to return True
185 | mock_is_mcp_managed.return_value = True
186 |
187 | # Create a mock MCP server
188 | mock_mcp = MagicMock()
189 |
190 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
191 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
192 | handler.glue_client = mock_glue_client
193 |
194 | # Create a mock context
195 | mock_ctx = MagicMock(spec=Context)
196 |
197 | # Mock the get_session response
198 | mock_glue_client.get_session.return_value = {
199 | 'Session': {'Id': 'test-session', 'Status': 'READY', 'Tags': {'ManagedBy': 'MCP'}}
200 | }
201 |
202 | # Call the manage_aws_glue_sessions method with delete-session operation
203 | result = await handler.manage_aws_glue_sessions(
204 | mock_ctx, operation='delete-session', session_id='test-session'
205 | )
206 |
207 | # Verify the result
208 | assert not result.isError
209 | assert len(result.content) == 1
210 | assert result.content[0].type == 'text'
211 | assert 'Successfully deleted session test-session' in result.content[0].text
212 | assert result.session_id == 'test-session'
213 |
214 | # Verify that delete_session was called with the correct parameters
215 | mock_glue_client.delete_session.assert_called_once()
216 | args, kwargs = mock_glue_client.delete_session.call_args
217 | assert kwargs['Id'] == 'test-session'
218 |
219 |
220 | @pytest.mark.asyncio
221 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
222 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
223 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
224 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
225 | async def test_delete_session_not_mcp_managed(
226 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
227 | ):
228 | # Create a mock Glue client
229 | mock_glue_client = MagicMock()
230 | mock_create_client.return_value = mock_glue_client
231 |
232 | # Mock the region and account ID
233 | mock_get_region.return_value = 'us-east-1'
234 | mock_get_account_id.return_value = '123456789012'
235 |
236 | # Mock the is_resource_mcp_managed to return False
237 | mock_is_mcp_managed.return_value = False
238 |
239 | # Create a mock MCP server
240 | mock_mcp = MagicMock()
241 |
242 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
243 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
244 | handler.glue_client = mock_glue_client
245 |
246 | # Create a mock context
247 | mock_ctx = MagicMock(spec=Context)
248 |
249 | # Mock the get_session response
250 | mock_glue_client.get_session.return_value = {
251 | 'Session': {
252 | 'Id': 'test-session',
253 | 'Status': 'READY',
254 | 'Tags': {}, # No MCP tags
255 | }
256 | }
257 |
258 | # Call the manage_aws_glue_sessions method with delete-session operation
259 | result = await handler.manage_aws_glue_sessions(
260 | mock_ctx, operation='delete-session', session_id='test-session'
261 | )
262 |
263 | # Verify the result indicates an error because the session is not MCP managed
264 | assert result.isError
265 | assert len(result.content) == 1
266 | assert result.content[0].type == 'text'
267 | assert (
268 | 'Cannot delete session test-session - it is not managed by the MCP server'
269 | in result.content[0].text
270 | )
271 | assert result.session_id == 'test-session'
272 |
273 | # Verify that delete_session was NOT called
274 | mock_glue_client.delete_session.assert_not_called()
275 |
276 |
277 | @pytest.mark.asyncio
278 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
279 | async def test_get_session_success(mock_create_client):
280 | # Create a mock Glue client
281 | mock_glue_client = MagicMock()
282 | mock_create_client.return_value = mock_glue_client
283 |
284 | # Create a mock MCP server
285 | mock_mcp = MagicMock()
286 |
287 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
288 | handler = GlueInteractiveSessionsHandler(mock_mcp)
289 | handler.glue_client = mock_glue_client
290 |
291 | # Create a mock context
292 | mock_ctx = MagicMock(spec=Context)
293 |
294 | # Mock the get_session response
295 | mock_session_details = {
296 | 'Id': 'test-session',
297 | 'Status': 'READY',
298 | 'Command': {'Name': 'glueetl', 'PythonVersion': '3'},
299 | 'GlueVersion': '3.0',
300 | }
301 | mock_glue_client.get_session.return_value = {'Session': mock_session_details}
302 |
303 | # Call the manage_aws_glue_sessions method with get-session operation
304 | result = await handler.manage_aws_glue_sessions(
305 | mock_ctx, operation='get-session', session_id='test-session'
306 | )
307 |
308 | # Verify the result
309 | assert not result.isError
310 | assert len(result.content) == 1
311 | assert result.content[0].type == 'text'
312 | assert 'Successfully retrieved session test-session' in result.content[0].text
313 | assert result.session_id == 'test-session'
314 | assert result.session == mock_session_details
315 |
316 | # Verify that get_session was called with the correct parameters
317 | mock_glue_client.get_session.assert_called()
318 | args, kwargs = mock_glue_client.get_session.call_args_list[-1]
319 | assert kwargs['Id'] == 'test-session'
320 |
321 |
322 | @pytest.mark.asyncio
323 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
324 | async def test_list_sessions_success(mock_create_client):
325 | # Create a mock Glue client
326 | mock_glue_client = MagicMock()
327 | mock_create_client.return_value = mock_glue_client
328 |
329 | # Create a mock MCP server
330 | mock_mcp = MagicMock()
331 |
332 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
333 | handler = GlueInteractiveSessionsHandler(mock_mcp)
334 | handler.glue_client = mock_glue_client
335 |
336 | # Create a mock context
337 | mock_ctx = MagicMock(spec=Context)
338 |
339 | # Mock the list_sessions response
340 | mock_glue_client.list_sessions.return_value = {
341 | 'Sessions': [
342 | {'Id': 'session1', 'Status': 'READY'},
343 | {'Id': 'session2', 'Status': 'PROVISIONING'},
344 | ],
345 | 'Ids': ['session1', 'session2'],
346 | 'NextToken': 'next-token',
347 | }
348 |
349 | # Call the manage_aws_glue_sessions method with list-sessions operation
350 | result = await handler.manage_aws_glue_sessions(
351 | mock_ctx,
352 | operation='list-sessions',
353 | max_results=10,
354 | next_token='token',
355 | tags={'Environment': 'Test'},
356 | )
357 |
358 | # Verify the result
359 | assert not result.isError
360 | assert len(result.content) == 1
361 | assert result.content[0].type == 'text'
362 | assert 'Successfully retrieved sessions' in result.content[0].text
363 | assert len(result.sessions) == 2
364 | assert result.sessions[0]['Id'] == 'session1'
365 | assert result.sessions[1]['Id'] == 'session2'
366 | assert result.ids == ['session1', 'session2']
367 | assert result.next_token == 'next-token'
368 | assert result.count == 2
369 |
370 | # Verify that list_sessions was called with the correct parameters
371 | mock_glue_client.list_sessions.assert_called_once()
372 | args, kwargs = mock_glue_client.list_sessions.call_args
373 | assert 'MaxResults' in kwargs
374 | # MaxResults is converted to string in the handler
375 | assert kwargs['MaxResults'] == '10'
376 | assert 'NextToken' in kwargs
377 | assert kwargs['NextToken'] == 'token'
378 | assert 'Tags' in kwargs
379 | assert kwargs['Tags'] == {'Environment': 'Test'}
380 |
381 |
382 | @pytest.mark.asyncio
383 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
384 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
385 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
386 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
387 | async def test_stop_session_success(
388 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
389 | ):
390 | # Create a mock Glue client
391 | mock_glue_client = MagicMock()
392 | mock_create_client.return_value = mock_glue_client
393 |
394 | # Mock the region and account ID
395 | mock_get_region.return_value = 'us-east-1'
396 | mock_get_account_id.return_value = '123456789012'
397 |
398 | # Mock the is_resource_mcp_managed to return True
399 | mock_is_mcp_managed.return_value = True
400 |
401 | # Create a mock MCP server
402 | mock_mcp = MagicMock()
403 |
404 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
405 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
406 | handler.glue_client = mock_glue_client
407 |
408 | # Create a mock context
409 | mock_ctx = MagicMock(spec=Context)
410 |
411 | # Mock the get_session response
412 | mock_glue_client.get_session.return_value = {
413 | 'Session': {'Id': 'test-session', 'Status': 'READY', 'Tags': {'ManagedBy': 'MCP'}}
414 | }
415 |
416 | # Call the manage_aws_glue_sessions method with stop-session operation
417 | result = await handler.manage_aws_glue_sessions(
418 | mock_ctx, operation='stop-session', session_id='test-session'
419 | )
420 |
421 | # Verify the result
422 | assert not result.isError
423 | assert len(result.content) == 1
424 | assert result.content[0].type == 'text'
425 | assert 'Successfully stopped session test-session' in result.content[0].text
426 | assert result.session_id == 'test-session'
427 |
428 | # Verify that stop_session was called with the correct parameters
429 | mock_glue_client.stop_session.assert_called_once()
430 | args, kwargs = mock_glue_client.stop_session.call_args
431 | assert kwargs['Id'] == 'test-session'
432 |
433 |
434 | @pytest.mark.asyncio
435 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
436 | async def test_session_not_found(mock_create_client):
437 | # Create a mock Glue client
438 | mock_glue_client = MagicMock()
439 | mock_create_client.return_value = mock_glue_client
440 |
441 | # Create a mock MCP server
442 | mock_mcp = MagicMock()
443 |
444 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
445 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
446 | handler.glue_client = mock_glue_client
447 |
448 | # Create a mock context
449 | mock_ctx = MagicMock(spec=Context)
450 |
451 | # Mock the get_session to raise EntityNotFoundException
452 | mock_glue_client.exceptions.EntityNotFoundException = ClientError(
453 | {'Error': {'Code': 'EntityNotFoundException', 'Message': 'Session not found'}},
454 | 'get_session',
455 | )
456 | mock_glue_client.get_session.side_effect = mock_glue_client.exceptions.EntityNotFoundException
457 |
458 | # Call the manage_aws_glue_sessions method with delete-session operation
459 | result = await handler.manage_aws_glue_sessions(
460 | mock_ctx, operation='delete-session', session_id='test-session'
461 | )
462 |
463 | # Verify the result indicates an error because the session was not found
464 | assert result.isError
465 | assert len(result.content) == 1
466 | assert result.content[0].type == 'text'
467 | assert 'Session test-session not found' in result.content[0].text
468 | assert result.session_id == 'test-session'
469 |
470 | # Verify that delete_session was NOT called
471 | mock_glue_client.delete_session.assert_not_called()
472 |
473 |
474 | @pytest.mark.asyncio
475 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
476 | async def test_session_invalid_operation(mock_create_client):
477 | # Create a mock Glue client
478 | mock_glue_client = MagicMock()
479 | mock_create_client.return_value = mock_glue_client
480 |
481 | # Create a mock MCP server
482 | mock_mcp = MagicMock()
483 |
484 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
485 | handler = GlueInteractiveSessionsHandler(mock_mcp)
486 | handler.glue_client = mock_glue_client
487 |
488 | # Create a mock context
489 | mock_ctx = MagicMock(spec=Context)
490 |
491 | # Call the manage_aws_glue_sessions method with an invalid operation
492 | result = await handler.manage_aws_glue_sessions(
493 | mock_ctx, operation='invalid-operation', session_id='test-session'
494 | )
495 |
496 | # Verify the result indicates an error due to invalid operation
497 | assert result.isError
498 | assert len(result.content) == 1
499 | assert result.content[0].type == 'text'
500 | assert 'Invalid operation: invalid-operation' in result.content[0].text
501 | assert result.session_id == 'test-session'
502 |
503 |
504 | # Tests for manage_aws_glue_statements method
505 |
506 |
507 | @pytest.mark.asyncio
508 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
509 | async def test_run_statement_success(mock_create_client):
510 | # Create a mock Glue client
511 | mock_glue_client = MagicMock()
512 | mock_create_client.return_value = mock_glue_client
513 |
514 | # Create a mock MCP server
515 | mock_mcp = MagicMock()
516 |
517 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
518 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
519 | handler.glue_client = mock_glue_client
520 |
521 | # Create a mock context
522 | mock_ctx = MagicMock(spec=Context)
523 |
524 | # Mock the run_statement response
525 | mock_glue_client.run_statement.return_value = {'Id': 1}
526 |
527 | # Call the manage_aws_glue_statements method with run-statement operation
528 | result = await handler.manage_aws_glue_statements(
529 | mock_ctx,
530 | operation='run-statement',
531 | session_id='test-session',
532 | code="df = spark.read.csv('s3://bucket/data.csv')\ndf.show(5)",
533 | )
534 |
535 | # Verify the result
536 | assert not result.isError
537 | assert len(result.content) == 1
538 | assert result.content[0].type == 'text'
539 | assert 'Successfully ran statement in session test-session' in result.content[0].text
540 | assert result.session_id == 'test-session'
541 | assert result.statement_id == 1
542 |
543 | # Verify that run_statement was called with the correct parameters
544 | mock_glue_client.run_statement.assert_called_once()
545 | args, kwargs = mock_glue_client.run_statement.call_args
546 | assert kwargs['SessionId'] == 'test-session'
547 | assert kwargs['Code'] == "df = spark.read.csv('s3://bucket/data.csv')\ndf.show(5)"
548 |
549 |
550 | @pytest.mark.asyncio
551 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
552 | async def test_run_statement_no_write_access(mock_create_client):
553 | # Create a mock Glue client
554 | mock_glue_client = MagicMock()
555 | mock_create_client.return_value = mock_glue_client
556 |
557 | # Create a mock MCP server
558 | mock_mcp = MagicMock()
559 |
560 | # Initialize the Glue Interactive Sessions handler with the mock MCP server without write access
561 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
562 | handler.glue_client = mock_glue_client
563 |
564 | # Create a mock context
565 | mock_ctx = MagicMock(spec=Context)
566 |
567 | # Call the manage_aws_glue_statements method with run-statement operation
568 | result = await handler.manage_aws_glue_statements(
569 | mock_ctx,
570 | operation='run-statement',
571 | session_id='test-session',
572 | code="df = spark.read.csv('s3://bucket/data.csv')\ndf.show(5)",
573 | )
574 |
575 | # Verify the result indicates an error due to no write access
576 | assert result.isError
577 | assert len(result.content) == 1
578 | assert result.content[0].type == 'text'
579 | assert 'Operation run-statement is not allowed without write access' in result.content[0].text
580 | assert result.session_id == ''
581 |
582 | # Verify that run_statement was NOT called
583 | mock_glue_client.run_statement.assert_not_called()
584 |
585 |
586 | @pytest.mark.asyncio
587 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
588 | async def test_cancel_statement_success(mock_create_client):
589 | # Create a mock Glue client
590 | mock_glue_client = MagicMock()
591 | mock_create_client.return_value = mock_glue_client
592 |
593 | # Create a mock MCP server
594 | mock_mcp = MagicMock()
595 |
596 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
597 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
598 | handler.glue_client = mock_glue_client
599 |
600 | # Create a mock context
601 | mock_ctx = MagicMock(spec=Context)
602 |
603 | # Call the manage_aws_glue_statements method with cancel-statement operation
604 | result = await handler.manage_aws_glue_statements(
605 | mock_ctx, operation='cancel-statement', session_id='test-session', statement_id=1
606 | )
607 |
608 | # Verify the result
609 | assert not result.isError
610 | assert len(result.content) == 1
611 | assert result.content[0].type == 'text'
612 | assert 'Successfully canceled statement 1 in session test-session' in result.content[0].text
613 | assert result.session_id == 'test-session'
614 | assert result.statement_id == 1
615 |
616 | # Verify that cancel_statement was called with the correct parameters
617 | mock_glue_client.cancel_statement.assert_called_once()
618 | args, kwargs = mock_glue_client.cancel_statement.call_args
619 | assert kwargs['SessionId'] == 'test-session'
620 | assert kwargs['Id'] == 1
621 |
622 |
623 | @pytest.mark.asyncio
624 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
625 | async def test_get_statement_success(mock_create_client):
626 | # Create a mock Glue client
627 | mock_glue_client = MagicMock()
628 | mock_create_client.return_value = mock_glue_client
629 |
630 | # Create a mock MCP server
631 | mock_mcp = MagicMock()
632 |
633 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
634 | handler = GlueInteractiveSessionsHandler(mock_mcp)
635 | handler.glue_client = mock_glue_client
636 |
637 | # Create a mock context
638 | mock_ctx = MagicMock(spec=Context)
639 |
640 | # Mock the get_statement response
641 | mock_statement_details = {
642 | 'Id': 1,
643 | 'Code': "df = spark.read.csv('s3://bucket/data.csv')\ndf.show(5)",
644 | 'State': 'AVAILABLE',
645 | 'Output': {
646 | 'Status': 'ok',
647 | 'Data': {
648 | 'text/plain': '+---+----+\n|id |name|\n+---+----+\n|1 |Alice|\n|2 |Bob |\n+---+----+'
649 | },
650 | },
651 | }
652 | mock_glue_client.get_statement.return_value = {'Statement': mock_statement_details}
653 |
654 | # Call the manage_aws_glue_statements method with get-statement operation
655 | result = await handler.manage_aws_glue_statements(
656 | mock_ctx, operation='get-statement', session_id='test-session', statement_id=1
657 | )
658 |
659 | # Verify the result
660 | assert not result.isError
661 | assert len(result.content) == 1
662 | assert result.content[0].type == 'text'
663 | assert 'Successfully retrieved statement 1 in session test-session' in result.content[0].text
664 | assert result.session_id == 'test-session'
665 | assert result.statement_id == 1
666 | assert result.statement == mock_statement_details
667 |
668 | # Verify that get_statement was called with the correct parameters
669 | mock_glue_client.get_statement.assert_called_once()
670 | args, kwargs = mock_glue_client.get_statement.call_args
671 | assert kwargs['SessionId'] == 'test-session'
672 | assert kwargs['Id'] == 1
673 |
674 |
675 | @pytest.mark.asyncio
676 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
677 | async def test_list_statements_success(mock_create_client):
678 | # Create a mock Glue client
679 | mock_glue_client = MagicMock()
680 | mock_create_client.return_value = mock_glue_client
681 |
682 | # Create a mock MCP server
683 | mock_mcp = MagicMock()
684 |
685 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
686 | handler = GlueInteractiveSessionsHandler(mock_mcp)
687 | handler.glue_client = mock_glue_client
688 |
689 | # Create a mock context
690 | mock_ctx = MagicMock(spec=Context)
691 |
692 | # Mock the list_statements response
693 | mock_glue_client.list_statements.return_value = {
694 | 'Statements': [{'Id': 1, 'State': 'AVAILABLE'}, {'Id': 2, 'State': 'RUNNING'}],
695 | 'NextToken': 'next-token',
696 | }
697 |
698 | # Call the manage_aws_glue_statements method with list-statements operation
699 | result = await handler.manage_aws_glue_statements(
700 | mock_ctx,
701 | operation='list-statements',
702 | session_id='test-session',
703 | max_results=10,
704 | next_token='token',
705 | )
706 |
707 | # Verify the result
708 | assert not result.isError
709 | assert len(result.content) == 1
710 | assert result.content[0].type == 'text'
711 | assert 'Successfully retrieved statements for session test-session' in result.content[0].text
712 | assert result.session_id == 'test-session'
713 | assert len(result.statements) == 2
714 | assert result.statements[0]['Id'] == 1
715 | assert result.statements[1]['Id'] == 2
716 | assert result.next_token == 'next-token'
717 | assert result.count == 2
718 |
719 | # Verify that list_statements was called with the correct parameters
720 | mock_glue_client.list_statements.assert_called_once()
721 | args, kwargs = mock_glue_client.list_statements.call_args
722 | assert kwargs['SessionId'] == 'test-session'
723 | assert 'MaxResults' in kwargs
724 | assert 'NextToken' in kwargs
725 |
726 |
727 | @pytest.mark.asyncio
728 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
729 | async def test_statement_invalid_operation(mock_create_client):
730 | # Create a mock Glue client
731 | mock_glue_client = MagicMock()
732 | mock_create_client.return_value = mock_glue_client
733 |
734 | # Create a mock MCP server
735 | mock_mcp = MagicMock()
736 |
737 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
738 | handler = GlueInteractiveSessionsHandler(mock_mcp)
739 | handler.glue_client = mock_glue_client
740 |
741 | # Create a mock context
742 | mock_ctx = MagicMock(spec=Context)
743 |
744 | # Call the manage_aws_glue_statements method with an invalid operation
745 | result = await handler.manage_aws_glue_statements(
746 | mock_ctx, operation='invalid-operation', session_id='test-session', statement_id=1
747 | )
748 |
749 | # Verify the result indicates an error due to invalid operation
750 | assert result.isError
751 | assert len(result.content) == 1
752 | assert result.content[0].type == 'text'
753 | assert 'Invalid operation: invalid-operation' in result.content[0].text
754 | assert result.session_id == 'test-session'
755 | assert result.statement_id == 1
756 |
757 |
758 | # Split the test_missing_required_parameters into individual tests for better isolation
759 |
760 |
761 | @pytest.mark.asyncio
762 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
763 | async def test_missing_role_and_command_for_create_session(mock_create_client):
764 | # Create a mock Glue client
765 | mock_glue_client = MagicMock()
766 | mock_create_client.return_value = mock_glue_client
767 |
768 | # Create a mock MCP server
769 | mock_mcp = MagicMock()
770 |
771 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
772 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
773 | handler.glue_client = mock_glue_client
774 |
775 | # Create a mock context
776 | mock_ctx = MagicMock(spec=Context)
777 |
778 | # Test missing role and command for create-session
779 | # The handler checks for None values, not missing parameters
780 | with pytest.raises(ValueError) as excinfo:
781 | await handler.manage_aws_glue_sessions(
782 | mock_ctx,
783 | operation='create-session',
784 | session_id='test-session',
785 | role=None,
786 | command=None,
787 | )
788 | assert 'role and command are required' in str(excinfo.value)
789 |
790 |
791 | @pytest.mark.asyncio
792 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
793 | async def test_missing_session_id_for_delete_session(mock_create_client):
794 | # Create a mock Glue client
795 | mock_glue_client = MagicMock()
796 | mock_create_client.return_value = mock_glue_client
797 |
798 | # Create a mock MCP server
799 | mock_mcp = MagicMock()
800 |
801 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
802 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
803 | handler.glue_client = mock_glue_client
804 |
805 | # Create a mock context
806 | mock_ctx = MagicMock(spec=Context)
807 |
808 | # Test missing session_id for delete-session
809 | with pytest.raises(ValueError) as excinfo:
810 | await handler.manage_aws_glue_sessions(
811 | mock_ctx, operation='delete-session', session_id=None
812 | )
813 | assert 'session_id is required' in str(excinfo.value)
814 |
815 |
816 | @pytest.mark.asyncio
817 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
818 | async def test_missing_session_id_for_get_session(mock_create_client):
819 | # Create a mock Glue client
820 | mock_glue_client = MagicMock()
821 | mock_create_client.return_value = mock_glue_client
822 |
823 | # Create a mock MCP server
824 | mock_mcp = MagicMock()
825 |
826 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
827 | handler = GlueInteractiveSessionsHandler(mock_mcp)
828 | handler.glue_client = mock_glue_client
829 |
830 | # Create a mock context
831 | mock_ctx = MagicMock(spec=Context)
832 |
833 | # Test missing session_id for get-session
834 | with pytest.raises(ValueError) as excinfo:
835 | await handler.manage_aws_glue_sessions(mock_ctx, operation='get-session', session_id=None)
836 | assert 'session_id is required' in str(excinfo.value)
837 |
838 |
839 | @pytest.mark.asyncio
840 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
841 | async def test_missing_session_id_for_stop_session(mock_create_client):
842 | # Create a mock Glue client
843 | mock_glue_client = MagicMock()
844 | mock_create_client.return_value = mock_glue_client
845 |
846 | # Create a mock MCP server
847 | mock_mcp = MagicMock()
848 |
849 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
850 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
851 | handler.glue_client = mock_glue_client
852 |
853 | # Create a mock context
854 | mock_ctx = MagicMock(spec=Context)
855 |
856 | # Test missing session_id for stop-session
857 | with pytest.raises(ValueError) as excinfo:
858 | await handler.manage_aws_glue_sessions(mock_ctx, operation='stop-session', session_id=None)
859 | assert 'session_id is required' in str(excinfo.value)
860 |
861 |
862 | @pytest.mark.asyncio
863 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
864 | async def test_missing_code_for_run_statement(mock_create_client):
865 | # Create a mock Glue client
866 | mock_glue_client = MagicMock()
867 | mock_create_client.return_value = mock_glue_client
868 |
869 | # Create a mock MCP server
870 | mock_mcp = MagicMock()
871 |
872 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
873 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
874 | handler.glue_client = mock_glue_client
875 |
876 | # Create a mock context
877 | mock_ctx = MagicMock(spec=Context)
878 |
879 | # Test missing code for run-statement
880 | with pytest.raises(ValueError) as excinfo:
881 | await handler.manage_aws_glue_statements(
882 | mock_ctx, operation='run-statement', session_id='test-session', code=None
883 | )
884 | assert 'code is required' in str(excinfo.value)
885 |
886 |
887 | @pytest.mark.asyncio
888 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
889 | async def test_missing_statement_id_for_cancel_statement(mock_create_client):
890 | # Create a mock Glue client
891 | mock_glue_client = MagicMock()
892 | mock_create_client.return_value = mock_glue_client
893 |
894 | # Create a mock MCP server
895 | mock_mcp = MagicMock()
896 |
897 | # Initialize the Glue Interactive Sessions handler with the mock MCP server
898 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
899 | handler.glue_client = mock_glue_client
900 |
901 | # Create a mock context
902 | mock_ctx = MagicMock(spec=Context)
903 |
904 | # Test missing statement_id for cancel-statement
905 | with pytest.raises(ValueError) as excinfo:
906 | await handler.manage_aws_glue_statements(
907 | mock_ctx, operation='cancel-statement', session_id='test-session', statement_id=None
908 | )
909 | assert 'statement_id is required' in str(excinfo.value)
910 |
911 |
912 | @pytest.mark.asyncio
913 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
914 | async def test_delete_session_no_write_access(mock_create_client):
915 | """Test delete session without write access."""
916 | mock_glue_client = MagicMock()
917 | mock_create_client.return_value = mock_glue_client
918 | mock_mcp = MagicMock()
919 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
920 | handler.glue_client = mock_glue_client
921 | mock_ctx = MagicMock(spec=Context)
922 |
923 | result = await handler.manage_aws_glue_sessions(
924 | mock_ctx, operation='delete-session', session_id='test-session'
925 | )
926 |
927 | assert result.isError
928 | assert 'Operation delete-session is not allowed without write access' in result.content[0].text
929 |
930 |
931 | @pytest.mark.asyncio
932 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
933 | async def test_stop_session_no_write_access(mock_create_client):
934 | """Test stop session without write access."""
935 | mock_glue_client = MagicMock()
936 | mock_create_client.return_value = mock_glue_client
937 | mock_mcp = MagicMock()
938 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
939 | handler.glue_client = mock_glue_client
940 | mock_ctx = MagicMock(spec=Context)
941 |
942 | result = await handler.manage_aws_glue_sessions(
943 | mock_ctx, operation='stop-session', session_id='test-session'
944 | )
945 |
946 | assert result.isError
947 | assert 'Operation stop-session is not allowed without write access' in result.content[0].text
948 |
949 |
950 | @pytest.mark.asyncio
951 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
952 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.prepare_resource_tags')
953 | async def test_create_session_with_all_optional_params(mock_prepare_tags, mock_create_client):
954 | """Test create session with all optional parameters."""
955 | mock_glue_client = MagicMock()
956 | mock_create_client.return_value = mock_glue_client
957 | mock_prepare_tags.return_value = {'ManagedBy': 'MCP'}
958 | mock_mcp = MagicMock()
959 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
960 | handler.glue_client = mock_glue_client
961 | mock_ctx = MagicMock(spec=Context)
962 |
963 | mock_glue_client.create_session.return_value = {
964 | 'Session': {'Id': 'test-session', 'Status': 'PROVISIONING'}
965 | }
966 |
967 | result = await handler.manage_aws_glue_sessions(
968 | mock_ctx,
969 | operation='create-session',
970 | session_id='test-session',
971 | role='arn:aws:iam::123456789012:role/GlueRole',
972 | command={'Name': 'glueetl'},
973 | description='Test description',
974 | timeout=120,
975 | idle_timeout=60,
976 | default_arguments={'--arg': 'value'},
977 | connections={'Connections': ['conn1']},
978 | max_capacity=2.0,
979 | number_of_workers=4,
980 | worker_type='G.2X',
981 | security_configuration='test-config',
982 | glue_version='4.0',
983 | request_origin='test-origin',
984 | )
985 |
986 | assert not result.isError
987 | args, kwargs = mock_glue_client.create_session.call_args
988 | assert kwargs['Description'] == 'Test description'
989 | assert kwargs['Timeout'] == 120
990 | assert kwargs['IdleTimeout'] == 60
991 | assert kwargs['DefaultArguments'] == {'--arg': 'value'}
992 | assert kwargs['Connections'] == {'Connections': ['conn1']}
993 | assert kwargs['MaxCapacity'] == 2.0
994 | assert kwargs['NumberOfWorkers'] == 4
995 | assert kwargs['WorkerType'] == 'G.2X'
996 | assert kwargs['SecurityConfiguration'] == 'test-config'
997 | assert kwargs['GlueVersion'] == '4.0'
998 | assert kwargs['RequestOrigin'] == 'test-origin'
999 |
1000 |
1001 | @pytest.mark.asyncio
1002 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1003 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.prepare_resource_tags')
1004 | async def test_create_session_without_user_tags(mock_prepare_tags, mock_create_client):
1005 | """Test create session without user-provided tags."""
1006 | mock_glue_client = MagicMock()
1007 | mock_create_client.return_value = mock_glue_client
1008 | mock_prepare_tags.return_value = {'ManagedBy': 'MCP'}
1009 | mock_mcp = MagicMock()
1010 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1011 | handler.glue_client = mock_glue_client
1012 | mock_ctx = MagicMock(spec=Context)
1013 |
1014 | mock_glue_client.create_session.return_value = {
1015 | 'Session': {'Id': 'test-session', 'Status': 'PROVISIONING'}
1016 | }
1017 |
1018 | result = await handler.manage_aws_glue_sessions(
1019 | mock_ctx,
1020 | operation='create-session',
1021 | session_id='test-session',
1022 | role='arn:aws:iam::123456789012:role/GlueRole',
1023 | command={'Name': 'glueetl'},
1024 | )
1025 |
1026 | assert not result.isError
1027 | args, kwargs = mock_glue_client.create_session.call_args
1028 | assert kwargs['Tags'] == {'ManagedBy': 'MCP'}
1029 |
1030 |
1031 | @pytest.mark.asyncio
1032 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1033 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1034 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1035 | async def test_delete_session_client_error(
1036 | mock_get_account_id, mock_get_region, mock_create_client
1037 | ):
1038 | """Test delete session with non-EntityNotFoundException ClientError."""
1039 | mock_glue_client = MagicMock()
1040 | mock_create_client.return_value = mock_glue_client
1041 | mock_get_region.return_value = 'us-east-1'
1042 | mock_get_account_id.return_value = '123456789012'
1043 | mock_mcp = MagicMock()
1044 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1045 | handler.glue_client = mock_glue_client
1046 | mock_ctx = MagicMock(spec=Context)
1047 |
1048 | mock_glue_client.get_session.side_effect = ClientError(
1049 | {'Error': {'Code': 'AccessDeniedException', 'Message': 'Access denied'}}, 'get_session'
1050 | )
1051 |
1052 | result = await handler.manage_aws_glue_sessions(
1053 | mock_ctx, operation='delete-session', session_id='test-session'
1054 | )
1055 |
1056 | assert result.isError
1057 | assert 'Error in manage_aws_glue_sessions' in result.content[0].text
1058 |
1059 |
1060 | @pytest.mark.asyncio
1061 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1062 | async def test_get_session_with_request_origin(mock_create_client):
1063 | """Test get session with request_origin."""
1064 | mock_glue_client = MagicMock()
1065 | mock_create_client.return_value = mock_glue_client
1066 | mock_mcp = MagicMock()
1067 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1068 | handler.glue_client = mock_glue_client
1069 | mock_ctx = MagicMock(spec=Context)
1070 |
1071 | mock_glue_client.get_session.return_value = {
1072 | 'Session': {'Id': 'test-session', 'Status': 'READY'}
1073 | }
1074 |
1075 | result = await handler.manage_aws_glue_sessions(
1076 | mock_ctx,
1077 | operation='get-session',
1078 | session_id='test-session',
1079 | request_origin='test-origin',
1080 | )
1081 |
1082 | assert not result.isError
1083 | args, kwargs = mock_glue_client.get_session.call_args
1084 | assert kwargs['RequestOrigin'] == 'test-origin'
1085 |
1086 |
1087 | @pytest.mark.asyncio
1088 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1089 | async def test_list_sessions_with_tags(mock_create_client):
1090 | """Test list sessions with tags parameter."""
1091 | mock_glue_client = MagicMock()
1092 | mock_create_client.return_value = mock_glue_client
1093 | mock_mcp = MagicMock()
1094 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1095 | handler.glue_client = mock_glue_client
1096 | mock_ctx = MagicMock(spec=Context)
1097 |
1098 | mock_glue_client.list_sessions.return_value = {
1099 | 'Sessions': [{'Id': 'session1'}],
1100 | 'Ids': ['session1'],
1101 | }
1102 |
1103 | result = await handler.manage_aws_glue_sessions(
1104 | mock_ctx,
1105 | operation='list-sessions',
1106 | tags={'Environment': 'Test'},
1107 | )
1108 |
1109 | assert not result.isError
1110 | args, kwargs = mock_glue_client.list_sessions.call_args
1111 | assert kwargs['Tags'] == {'Environment': 'Test'}
1112 |
1113 |
1114 | @pytest.mark.asyncio
1115 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1116 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1117 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1118 | async def test_stop_session_client_error(mock_get_account_id, mock_get_region, mock_create_client):
1119 | """Test stop session with non-EntityNotFoundException ClientError."""
1120 | mock_glue_client = MagicMock()
1121 | mock_create_client.return_value = mock_glue_client
1122 | mock_get_region.return_value = 'us-east-1'
1123 | mock_get_account_id.return_value = '123456789012'
1124 | mock_mcp = MagicMock()
1125 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1126 | handler.glue_client = mock_glue_client
1127 | mock_ctx = MagicMock(spec=Context)
1128 |
1129 | mock_glue_client.get_session.side_effect = ClientError(
1130 | {'Error': {'Code': 'AccessDeniedException', 'Message': 'Access denied'}}, 'get_session'
1131 | )
1132 |
1133 | result = await handler.manage_aws_glue_sessions(
1134 | mock_ctx, operation='stop-session', session_id='test-session'
1135 | )
1136 |
1137 | assert result.isError
1138 | assert 'Error in manage_aws_glue_sessions' in result.content[0].text
1139 |
1140 |
1141 | @pytest.mark.asyncio
1142 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1143 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1144 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1145 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
1146 | async def test_stop_session_with_request_origin(
1147 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
1148 | ):
1149 | """Test stop session with request_origin."""
1150 | mock_glue_client = MagicMock()
1151 | mock_create_client.return_value = mock_glue_client
1152 | mock_get_region.return_value = 'us-east-1'
1153 | mock_get_account_id.return_value = '123456789012'
1154 | mock_is_mcp_managed.return_value = True
1155 | mock_mcp = MagicMock()
1156 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1157 | handler.glue_client = mock_glue_client
1158 | mock_ctx = MagicMock(spec=Context)
1159 |
1160 | mock_glue_client.get_session.return_value = {
1161 | 'Session': {'Id': 'test-session', 'Tags': {'ManagedBy': 'MCP'}}
1162 | }
1163 |
1164 | result = await handler.manage_aws_glue_sessions(
1165 | mock_ctx,
1166 | operation='stop-session',
1167 | session_id='test-session',
1168 | request_origin='test-origin',
1169 | )
1170 |
1171 | assert not result.isError
1172 | get_args, get_kwargs = mock_glue_client.get_session.call_args
1173 | assert get_kwargs['RequestOrigin'] == 'test-origin'
1174 | stop_args, stop_kwargs = mock_glue_client.stop_session.call_args
1175 | assert stop_kwargs['RequestOrigin'] == 'test-origin'
1176 |
1177 |
1178 | @pytest.mark.asyncio
1179 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1180 | async def test_invalid_session_operation(mock_create_client):
1181 | """Test invalid session operation."""
1182 | mock_glue_client = MagicMock()
1183 | mock_create_client.return_value = mock_glue_client
1184 | mock_mcp = MagicMock()
1185 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1186 | handler.glue_client = mock_glue_client
1187 | mock_ctx = MagicMock(spec=Context)
1188 |
1189 | result = await handler.manage_aws_glue_sessions(
1190 | mock_ctx, operation='invalid-operation', session_id='test-session'
1191 | )
1192 |
1193 | assert result.isError
1194 | assert 'Invalid operation: invalid-operation' in result.content[0].text
1195 |
1196 |
1197 | @pytest.mark.asyncio
1198 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1199 | async def test_cancel_statement_no_write_access(mock_create_client):
1200 | """Test cancel statement without write access."""
1201 | mock_glue_client = MagicMock()
1202 | mock_create_client.return_value = mock_glue_client
1203 | mock_mcp = MagicMock()
1204 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
1205 | handler.glue_client = mock_glue_client
1206 | mock_ctx = MagicMock(spec=Context)
1207 |
1208 | result = await handler.manage_aws_glue_statements(
1209 | mock_ctx, operation='cancel-statement', session_id='test-session', statement_id=1
1210 | )
1211 |
1212 | assert result.isError
1213 | assert (
1214 | 'Operation cancel-statement is not allowed without write access' in result.content[0].text
1215 | )
1216 |
1217 |
1218 | @pytest.mark.asyncio
1219 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1220 | async def test_run_statement_with_request_origin(mock_create_client):
1221 | """Test run statement with request_origin."""
1222 | mock_glue_client = MagicMock()
1223 | mock_create_client.return_value = mock_glue_client
1224 | mock_mcp = MagicMock()
1225 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1226 | handler.glue_client = mock_glue_client
1227 | mock_ctx = MagicMock(spec=Context)
1228 |
1229 | mock_glue_client.run_statement.return_value = {'Id': 1}
1230 |
1231 | result = await handler.manage_aws_glue_statements(
1232 | mock_ctx,
1233 | operation='run-statement',
1234 | session_id='test-session',
1235 | code='print("hello")',
1236 | request_origin='test-origin',
1237 | )
1238 |
1239 | assert not result.isError
1240 | args, kwargs = mock_glue_client.run_statement.call_args
1241 | assert kwargs['RequestOrigin'] == 'test-origin'
1242 |
1243 |
1244 | @pytest.mark.asyncio
1245 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1246 | async def test_cancel_statement_with_request_origin(mock_create_client):
1247 | """Test cancel statement with request_origin."""
1248 | mock_glue_client = MagicMock()
1249 | mock_create_client.return_value = mock_glue_client
1250 | mock_mcp = MagicMock()
1251 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1252 | handler.glue_client = mock_glue_client
1253 | mock_ctx = MagicMock(spec=Context)
1254 |
1255 | result = await handler.manage_aws_glue_statements(
1256 | mock_ctx,
1257 | operation='cancel-statement',
1258 | session_id='test-session',
1259 | statement_id=1,
1260 | request_origin='test-origin',
1261 | )
1262 |
1263 | assert not result.isError
1264 | args, kwargs = mock_glue_client.cancel_statement.call_args
1265 | assert kwargs['RequestOrigin'] == 'test-origin'
1266 |
1267 |
1268 | @pytest.mark.asyncio
1269 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1270 | async def test_get_statement_with_request_origin(mock_create_client):
1271 | """Test get statement with request_origin."""
1272 | mock_glue_client = MagicMock()
1273 | mock_create_client.return_value = mock_glue_client
1274 | mock_mcp = MagicMock()
1275 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1276 | handler.glue_client = mock_glue_client
1277 | mock_ctx = MagicMock(spec=Context)
1278 |
1279 | mock_glue_client.get_statement.return_value = {'Statement': {'Id': 1, 'State': 'AVAILABLE'}}
1280 |
1281 | result = await handler.manage_aws_glue_statements(
1282 | mock_ctx,
1283 | operation='get-statement',
1284 | session_id='test-session',
1285 | statement_id=1,
1286 | request_origin='test-origin',
1287 | )
1288 |
1289 | assert not result.isError
1290 | args, kwargs = mock_glue_client.get_statement.call_args
1291 | assert kwargs['RequestOrigin'] == 'test-origin'
1292 |
1293 |
1294 | @pytest.mark.asyncio
1295 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1296 | async def test_list_statements_with_pagination(mock_create_client):
1297 | """Test list statements with max_results and next_token."""
1298 | mock_glue_client = MagicMock()
1299 | mock_create_client.return_value = mock_glue_client
1300 | mock_mcp = MagicMock()
1301 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1302 | handler.glue_client = mock_glue_client
1303 | mock_ctx = MagicMock(spec=Context)
1304 |
1305 | mock_glue_client.list_statements.return_value = {
1306 | 'Statements': [{'Id': 1}],
1307 | 'NextToken': 'next-token',
1308 | }
1309 |
1310 | result = await handler.manage_aws_glue_statements(
1311 | mock_ctx,
1312 | operation='list-statements',
1313 | session_id='test-session',
1314 | max_results=10,
1315 | next_token='token',
1316 | )
1317 |
1318 | assert not result.isError
1319 | args, kwargs = mock_glue_client.list_statements.call_args
1320 | assert kwargs['MaxResults'] == '10'
1321 | assert kwargs['NextToken'] == 'token'
1322 |
1323 |
1324 | @pytest.mark.asyncio
1325 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1326 | async def test_list_statements_with_request_origin(mock_create_client):
1327 | """Test list statements with request_origin."""
1328 | mock_glue_client = MagicMock()
1329 | mock_create_client.return_value = mock_glue_client
1330 | mock_mcp = MagicMock()
1331 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1332 | handler.glue_client = mock_glue_client
1333 | mock_ctx = MagicMock(spec=Context)
1334 |
1335 | mock_glue_client.list_statements.return_value = {
1336 | 'Statements': [{'Id': 1}],
1337 | }
1338 |
1339 | result = await handler.manage_aws_glue_statements(
1340 | mock_ctx,
1341 | operation='list-statements',
1342 | session_id='test-session',
1343 | request_origin='test-origin',
1344 | )
1345 |
1346 | assert not result.isError
1347 | args, kwargs = mock_glue_client.list_statements.call_args
1348 | assert kwargs['RequestOrigin'] == 'test-origin'
1349 |
1350 |
1351 | @pytest.mark.asyncio
1352 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1353 | async def test_invalid_statement_operation(mock_create_client):
1354 | """Test invalid statement operation."""
1355 | mock_glue_client = MagicMock()
1356 | mock_create_client.return_value = mock_glue_client
1357 | mock_mcp = MagicMock()
1358 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1359 | handler.glue_client = mock_glue_client
1360 | mock_ctx = MagicMock(spec=Context)
1361 |
1362 | result = await handler.manage_aws_glue_statements(
1363 | mock_ctx, operation='invalid-operation', session_id='test-session', statement_id=1
1364 | )
1365 |
1366 | assert result.isError
1367 | assert 'Invalid operation: invalid-operation' in result.content[0].text
1368 |
1369 |
1370 | @pytest.mark.asyncio
1371 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1372 | async def test_statements_general_exception(mock_create_client):
1373 | """Test general exception handling in statements."""
1374 | mock_glue_client = MagicMock()
1375 | mock_glue_client.get_statement.side_effect = Exception('Test exception')
1376 | mock_create_client.return_value = mock_glue_client
1377 | mock_mcp = MagicMock()
1378 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1379 | handler.glue_client = mock_glue_client
1380 | mock_ctx = MagicMock(spec=Context)
1381 |
1382 | result = await handler.manage_aws_glue_statements(
1383 | mock_ctx, operation='get-statement', session_id='test-session', statement_id=1
1384 | )
1385 |
1386 | assert result.isError
1387 | assert 'Error in manage_aws_glue_statements: Test exception' in result.content[0].text
1388 |
1389 |
1390 | @pytest.mark.asyncio
1391 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1392 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1393 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1394 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
1395 | async def test_stop_session_not_mcp_managed(
1396 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
1397 | ):
1398 | """Test stop session when session is not MCP managed."""
1399 | mock_glue_client = MagicMock()
1400 | mock_create_client.return_value = mock_glue_client
1401 | mock_get_region.return_value = 'us-east-1'
1402 | mock_get_account_id.return_value = '123456789012'
1403 | mock_is_mcp_managed.return_value = False
1404 | mock_mcp = MagicMock()
1405 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1406 | handler.glue_client = mock_glue_client
1407 | mock_ctx = MagicMock(spec=Context)
1408 |
1409 | mock_glue_client.get_session.return_value = {'Session': {'Id': 'test-session', 'Tags': {}}}
1410 |
1411 | result = await handler.manage_aws_glue_sessions(
1412 | mock_ctx, operation='stop-session', session_id='test-session'
1413 | )
1414 |
1415 | assert result.isError
1416 | assert (
1417 | 'Cannot stop session test-session - it is not managed by the MCP server'
1418 | in result.content[0].text
1419 | )
1420 |
1421 |
1422 | @pytest.mark.asyncio
1423 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1424 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1425 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1426 | async def test_stop_session_not_found(mock_get_account_id, mock_get_region, mock_create_client):
1427 | """Test stop session when session is not found."""
1428 | mock_glue_client = MagicMock()
1429 | mock_create_client.return_value = mock_glue_client
1430 | mock_get_region.return_value = 'us-east-1'
1431 | mock_get_account_id.return_value = '123456789012'
1432 | mock_mcp = MagicMock()
1433 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1434 | handler.glue_client = mock_glue_client
1435 | mock_ctx = MagicMock(spec=Context)
1436 |
1437 | mock_glue_client.get_session.side_effect = ClientError(
1438 | {'Error': {'Code': 'EntityNotFoundException', 'Message': 'Session not found'}},
1439 | 'get_session',
1440 | )
1441 |
1442 | result = await handler.manage_aws_glue_sessions(
1443 | mock_ctx, operation='stop-session', session_id='test-session'
1444 | )
1445 |
1446 | assert result.isError
1447 | assert 'Session test-session not found' in result.content[0].text
1448 |
1449 |
1450 | @pytest.mark.asyncio
1451 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1452 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.prepare_resource_tags')
1453 | async def test_create_session_individual_params(mock_prepare_tags, mock_create_client):
1454 | """Test create session with individual optional parameters."""
1455 | mock_glue_client = MagicMock()
1456 | mock_create_client.return_value = mock_glue_client
1457 | mock_prepare_tags.return_value = {'ManagedBy': 'MCP'}
1458 | mock_mcp = MagicMock()
1459 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1460 | handler.glue_client = mock_glue_client
1461 | mock_ctx = MagicMock(spec=Context)
1462 |
1463 | mock_glue_client.create_session.return_value = {
1464 | 'Session': {'Id': 'test-session', 'Status': 'PROVISIONING'}
1465 | }
1466 |
1467 | # Test with description only
1468 | await handler.manage_aws_glue_sessions(
1469 | mock_ctx,
1470 | operation='create-session',
1471 | session_id='test-session',
1472 | role='arn:aws:iam::123456789012:role/GlueRole',
1473 | command={'Name': 'glueetl'},
1474 | description='Test description',
1475 | )
1476 |
1477 | # Test with timeout only
1478 | await handler.manage_aws_glue_sessions(
1479 | mock_ctx,
1480 | operation='create-session',
1481 | session_id='test-session',
1482 | role='arn:aws:iam::123456789012:role/GlueRole',
1483 | command={'Name': 'glueetl'},
1484 | timeout=120,
1485 | )
1486 |
1487 | # Test with idle_timeout only
1488 | await handler.manage_aws_glue_sessions(
1489 | mock_ctx,
1490 | operation='create-session',
1491 | session_id='test-session',
1492 | role='arn:aws:iam::123456789012:role/GlueRole',
1493 | command={'Name': 'glueetl'},
1494 | idle_timeout=60,
1495 | )
1496 |
1497 | # Test with default_arguments only
1498 | await handler.manage_aws_glue_sessions(
1499 | mock_ctx,
1500 | operation='create-session',
1501 | session_id='test-session',
1502 | role='arn:aws:iam::123456789012:role/GlueRole',
1503 | command={'Name': 'glueetl'},
1504 | default_arguments={'--arg': 'value'},
1505 | )
1506 |
1507 | # Test with connections only
1508 | await handler.manage_aws_glue_sessions(
1509 | mock_ctx,
1510 | operation='create-session',
1511 | session_id='test-session',
1512 | role='arn:aws:iam::123456789012:role/GlueRole',
1513 | command={'Name': 'glueetl'},
1514 | connections={'Connections': ['conn1']},
1515 | )
1516 |
1517 | # Test with max_capacity only
1518 | await handler.manage_aws_glue_sessions(
1519 | mock_ctx,
1520 | operation='create-session',
1521 | session_id='test-session',
1522 | role='arn:aws:iam::123456789012:role/GlueRole',
1523 | command={'Name': 'glueetl'},
1524 | max_capacity=2.0,
1525 | )
1526 |
1527 | # Test with number_of_workers only
1528 | await handler.manage_aws_glue_sessions(
1529 | mock_ctx,
1530 | operation='create-session',
1531 | session_id='test-session',
1532 | role='arn:aws:iam::123456789012:role/GlueRole',
1533 | command={'Name': 'glueetl'},
1534 | number_of_workers=4,
1535 | )
1536 |
1537 | # Test with worker_type only
1538 | await handler.manage_aws_glue_sessions(
1539 | mock_ctx,
1540 | operation='create-session',
1541 | session_id='test-session',
1542 | role='arn:aws:iam::123456789012:role/GlueRole',
1543 | command={'Name': 'glueetl'},
1544 | worker_type='G.2X',
1545 | )
1546 |
1547 | # Test with security_configuration only
1548 | await handler.manage_aws_glue_sessions(
1549 | mock_ctx,
1550 | operation='create-session',
1551 | session_id='test-session',
1552 | role='arn:aws:iam::123456789012:role/GlueRole',
1553 | command={'Name': 'glueetl'},
1554 | security_configuration='test-config',
1555 | )
1556 |
1557 | # Test with glue_version only
1558 | await handler.manage_aws_glue_sessions(
1559 | mock_ctx,
1560 | operation='create-session',
1561 | session_id='test-session',
1562 | role='arn:aws:iam::123456789012:role/GlueRole',
1563 | command={'Name': 'glueetl'},
1564 | glue_version='4.0',
1565 | )
1566 |
1567 | assert mock_glue_client.create_session.call_count == 10
1568 |
1569 |
1570 | @pytest.mark.asyncio
1571 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1572 | async def test_missing_session_id_for_list_statements(mock_create_client):
1573 | """Test missing session_id for list-statements."""
1574 | mock_glue_client = MagicMock()
1575 | mock_create_client.return_value = mock_glue_client
1576 | mock_mcp = MagicMock()
1577 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1578 | handler.glue_client = mock_glue_client
1579 | mock_ctx = MagicMock(spec=Context)
1580 |
1581 | with pytest.raises(Exception) as excinfo:
1582 | await handler.manage_aws_glue_statements(
1583 | mock_ctx, operation='list-statements', session_id=None
1584 | )
1585 | assert 'validation errors' in str(excinfo.value)
1586 |
1587 |
1588 | @pytest.mark.asyncio
1589 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1590 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1591 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1592 | async def test_delete_session_entity_not_found(
1593 | mock_get_account_id, mock_get_region, mock_create_client
1594 | ):
1595 | """Test delete session when session is not found."""
1596 | mock_glue_client = MagicMock()
1597 | mock_create_client.return_value = mock_glue_client
1598 | mock_get_region.return_value = 'us-east-1'
1599 | mock_get_account_id.return_value = '123456789012'
1600 | mock_mcp = MagicMock()
1601 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1602 | handler.glue_client = mock_glue_client
1603 | mock_ctx = MagicMock(spec=Context)
1604 |
1605 | mock_glue_client.get_session.side_effect = ClientError(
1606 | {'Error': {'Code': 'EntityNotFoundException', 'Message': 'Session not found'}},
1607 | 'get_session',
1608 | )
1609 |
1610 | result = await handler.manage_aws_glue_sessions(
1611 | mock_ctx, operation='delete-session', session_id='test-session'
1612 | )
1613 |
1614 | assert result.isError
1615 | assert 'Session test-session not found' in result.content[0].text
1616 |
1617 |
1618 | @pytest.mark.asyncio
1619 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1620 | async def test_get_session_without_request_origin(mock_create_client):
1621 | """Test get session without request_origin."""
1622 | mock_glue_client = MagicMock()
1623 | mock_create_client.return_value = mock_glue_client
1624 | mock_mcp = MagicMock()
1625 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1626 | handler.glue_client = mock_glue_client
1627 | mock_ctx = MagicMock(spec=Context)
1628 |
1629 | mock_glue_client.get_session.return_value = {
1630 | 'Session': {'Id': 'test-session', 'Status': 'READY'}
1631 | }
1632 |
1633 | result = await handler.manage_aws_glue_sessions(
1634 | mock_ctx, operation='get-session', session_id='test-session'
1635 | )
1636 |
1637 | assert not result.isError
1638 |
1639 |
1640 | @pytest.mark.asyncio
1641 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1642 | async def test_list_sessions_without_optional_params(mock_create_client):
1643 | """Test list sessions without optional parameters."""
1644 | mock_glue_client = MagicMock()
1645 | mock_create_client.return_value = mock_glue_client
1646 | mock_mcp = MagicMock()
1647 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1648 | handler.glue_client = mock_glue_client
1649 | mock_ctx = MagicMock(spec=Context)
1650 |
1651 | mock_glue_client.list_sessions.return_value = {
1652 | 'Sessions': [{'Id': 'session1'}],
1653 | 'Ids': ['session1'],
1654 | }
1655 |
1656 | result = await handler.manage_aws_glue_sessions(mock_ctx, operation='list-sessions')
1657 |
1658 | assert not result.isError
1659 |
1660 |
1661 | @pytest.mark.asyncio
1662 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1663 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_region')
1664 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.get_aws_account_id')
1665 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.is_resource_mcp_managed')
1666 | async def test_stop_session_without_request_origin(
1667 | mock_is_mcp_managed, mock_get_account_id, mock_get_region, mock_create_client
1668 | ):
1669 | """Test stop session without request_origin."""
1670 | mock_glue_client = MagicMock()
1671 | mock_create_client.return_value = mock_glue_client
1672 | mock_get_region.return_value = 'us-east-1'
1673 | mock_get_account_id.return_value = '123456789012'
1674 | mock_is_mcp_managed.return_value = True
1675 | mock_mcp = MagicMock()
1676 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1677 | handler.glue_client = mock_glue_client
1678 | mock_ctx = MagicMock(spec=Context)
1679 |
1680 | mock_glue_client.get_session.return_value = {
1681 | 'Session': {'Id': 'test-session', 'Tags': {'ManagedBy': 'MCP'}}
1682 | }
1683 |
1684 | result = await handler.manage_aws_glue_sessions(
1685 | mock_ctx, operation='stop-session', session_id='test-session'
1686 | )
1687 |
1688 | assert not result.isError
1689 |
1690 |
1691 | @pytest.mark.asyncio
1692 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1693 | async def test_run_statement_without_request_origin(mock_create_client):
1694 | """Test run statement without request_origin."""
1695 | mock_glue_client = MagicMock()
1696 | mock_create_client.return_value = mock_glue_client
1697 | mock_mcp = MagicMock()
1698 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1699 | handler.glue_client = mock_glue_client
1700 | mock_ctx = MagicMock(spec=Context)
1701 |
1702 | mock_glue_client.run_statement.return_value = {'Id': 1}
1703 |
1704 | result = await handler.manage_aws_glue_statements(
1705 | mock_ctx, operation='run-statement', session_id='test-session', code='print("hello")'
1706 | )
1707 |
1708 | assert not result.isError
1709 |
1710 |
1711 | @pytest.mark.asyncio
1712 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1713 | async def test_get_statement_without_request_origin(mock_create_client):
1714 | """Test get statement without request_origin."""
1715 | mock_glue_client = MagicMock()
1716 | mock_create_client.return_value = mock_glue_client
1717 | mock_mcp = MagicMock()
1718 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1719 | handler.glue_client = mock_glue_client
1720 | mock_ctx = MagicMock(spec=Context)
1721 |
1722 | mock_glue_client.get_statement.return_value = {'Statement': {'Id': 1, 'State': 'AVAILABLE'}}
1723 |
1724 | result = await handler.manage_aws_glue_statements(
1725 | mock_ctx, operation='get-statement', session_id='test-session', statement_id=1
1726 | )
1727 |
1728 | assert not result.isError
1729 |
1730 |
1731 | @pytest.mark.asyncio
1732 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1733 | async def test_list_statements_without_optional_params(mock_create_client):
1734 | """Test list statements without optional parameters."""
1735 | mock_glue_client = MagicMock()
1736 | mock_create_client.return_value = mock_glue_client
1737 | mock_mcp = MagicMock()
1738 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1739 | handler.glue_client = mock_glue_client
1740 | mock_ctx = MagicMock(spec=Context)
1741 |
1742 | mock_glue_client.list_statements.return_value = {
1743 | 'Statements': [{'Id': 1}],
1744 | }
1745 |
1746 | result = await handler.manage_aws_glue_statements(
1747 | mock_ctx, operation='list-statements', session_id='test-session'
1748 | )
1749 |
1750 | assert not result.isError
1751 |
1752 |
1753 | @pytest.mark.asyncio
1754 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1755 | async def test_cancel_statement_without_request_origin(mock_create_client):
1756 | """Test cancel statement without request_origin."""
1757 | mock_glue_client = MagicMock()
1758 | mock_create_client.return_value = mock_glue_client
1759 | mock_mcp = MagicMock()
1760 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1761 | handler.glue_client = mock_glue_client
1762 | mock_ctx = MagicMock(spec=Context)
1763 |
1764 | result = await handler.manage_aws_glue_statements(
1765 | mock_ctx, operation='cancel-statement', session_id='test-session', statement_id=1
1766 | )
1767 |
1768 | assert not result.isError
1769 |
1770 |
1771 | @pytest.mark.asyncio
1772 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1773 | async def test_session_parameter_validation_errors(mock_create_client):
1774 | """Test session parameter validation errors."""
1775 | mock_glue_client = MagicMock()
1776 | mock_create_client.return_value = mock_glue_client
1777 | mock_mcp = MagicMock()
1778 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1779 | handler.glue_client = mock_glue_client
1780 | mock_ctx = MagicMock(spec=Context)
1781 |
1782 | # Test missing session_id for various operations
1783 | operations = ['delete-session', 'get-session', 'stop-session']
1784 | for operation in operations:
1785 | with pytest.raises(ValueError) as excinfo:
1786 | await handler.manage_aws_glue_sessions(mock_ctx, operation=operation, session_id=None)
1787 | assert 'session_id is required' in str(excinfo.value)
1788 |
1789 |
1790 | @pytest.mark.asyncio
1791 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1792 | async def test_statement_parameter_validation_errors(mock_create_client):
1793 | """Test statement parameter validation errors."""
1794 | mock_glue_client = MagicMock()
1795 | mock_create_client.return_value = mock_glue_client
1796 | mock_mcp = MagicMock()
1797 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1798 | handler.glue_client = mock_glue_client
1799 | mock_ctx = MagicMock(spec=Context)
1800 |
1801 | # Test missing statement_id for operations that require it
1802 | operations = ['cancel-statement', 'get-statement']
1803 | for operation in operations:
1804 | with pytest.raises(ValueError) as excinfo:
1805 | await handler.manage_aws_glue_statements(
1806 | mock_ctx, operation=operation, session_id='test-session', statement_id=None
1807 | )
1808 | assert 'statement_id is required' in str(excinfo.value)
1809 |
1810 |
1811 | @pytest.mark.asyncio
1812 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1813 | async def test_sessions_general_exception(mock_create_client):
1814 | """Test general exception handling in sessions."""
1815 | mock_glue_client = MagicMock()
1816 | mock_glue_client.get_session.side_effect = Exception('Test exception')
1817 | mock_create_client.return_value = mock_glue_client
1818 | mock_mcp = MagicMock()
1819 | handler = GlueInteractiveSessionsHandler(mock_mcp)
1820 | handler.glue_client = mock_glue_client
1821 | mock_ctx = MagicMock(spec=Context)
1822 |
1823 | result = await handler.manage_aws_glue_sessions(
1824 | mock_ctx, operation='get-session', session_id='test-session'
1825 | )
1826 |
1827 | assert result.isError is True
1828 | assert 'Error in manage_aws_glue_sessions: Test exception' in result.content[0].text
1829 |
1830 |
1831 | @pytest.mark.asyncio
1832 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1833 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.prepare_resource_tags')
1834 | async def test_create_session_minimal_params(mock_prepare_tags, mock_create_client):
1835 | """Test create session with minimal required parameters."""
1836 | mock_glue_client = MagicMock()
1837 | mock_create_client.return_value = mock_glue_client
1838 | mock_prepare_tags.return_value = {'ManagedBy': 'MCP'}
1839 | mock_mcp = MagicMock()
1840 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=True)
1841 | handler.glue_client = mock_glue_client
1842 | mock_ctx = MagicMock(spec=Context)
1843 |
1844 | mock_glue_client.create_session.return_value = {
1845 | 'Session': {'Id': 'test-session', 'Status': 'PROVISIONING'}
1846 | }
1847 |
1848 | result = await handler.manage_aws_glue_sessions(
1849 | mock_ctx,
1850 | operation='create-session',
1851 | session_id='test-session',
1852 | role='arn:aws:iam::123456789012:role/GlueRole',
1853 | command={'Name': 'glueetl'},
1854 | )
1855 |
1856 | assert result.isError is False
1857 | # Just verify the call was made with required parameters
1858 | mock_glue_client.create_session.assert_called_once()
1859 | args, kwargs = mock_glue_client.create_session.call_args
1860 | assert kwargs['Id'] == 'test-session'
1861 | assert kwargs['Role'] == 'arn:aws:iam::123456789012:role/GlueRole'
1862 | assert kwargs['Command'] == {'Name': 'glueetl'}
1863 |
1864 |
1865 | @pytest.mark.asyncio
1866 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1867 | async def test_session_no_write_access_fallback(mock_create_client):
1868 | """Test sessions no write access fallback response."""
1869 | mock_glue_client = MagicMock()
1870 | mock_create_client.return_value = mock_glue_client
1871 | mock_mcp = MagicMock()
1872 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
1873 | handler.glue_client = mock_glue_client
1874 | mock_ctx = MagicMock(spec=Context)
1875 |
1876 | result = await handler.manage_aws_glue_sessions(
1877 | mock_ctx, operation='unknown-operation', session_id='test-session'
1878 | )
1879 |
1880 | assert result.isError is True
1881 | assert 'Invalid operation: unknown-operation' in result.content[0].text
1882 |
1883 |
1884 | @pytest.mark.asyncio
1885 | @patch('awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client')
1886 | async def test_statement_no_write_access_fallback(mock_create_client):
1887 | """Test statements no write access fallback response."""
1888 | mock_glue_client = MagicMock()
1889 | mock_create_client.return_value = mock_glue_client
1890 | mock_mcp = MagicMock()
1891 | handler = GlueInteractiveSessionsHandler(mock_mcp, allow_write=False)
1892 | handler.glue_client = mock_glue_client
1893 | mock_ctx = MagicMock(spec=Context)
1894 |
1895 | result = await handler.manage_aws_glue_statements(
1896 | mock_ctx, operation='run-statement', session_id='test-session'
1897 | )
1898 |
1899 | assert result.isError is True
1900 | assert 'Operation run-statement is not allowed without write access' in result.content[0].text
1901 |
```