It starts in `READ_ONLY`, so the careless configuration is the harmless one, and the denylist stays in force even at the loosest setting — you cannot turn off logging or schedule a KMS key for deletion through it at all. What justifies a unified server rather than a per-service one is `discover_resources`, `map_dependencies` and `impact_analysis`: those questions cross service boundaries by definition, and no single-service server can answer them. Point it at LocalStack while you are learning what it does.
A FastMCP server for AWS that unifies what is normally split across many service-specific servers into 30 tools. Rather than one tool per API call, it takes a natural-language query, validates it against botocore's own service models, and executes it — which is what makes cross-service questions like "what depends on this security group" answerable at all.
- AWS queried in natural language, with an operation checked for validity before it runs and executed only when it is — `aws_query`, `validate_operation`, `aws_execute`
- A three-tier safety system: `READ_ONLY` by default allowing only list, describe and get; `STANDARD` adding writes with confirmation; `UNRESTRICTED` allowing everything except a denylist of 70+ operations that are always blocked, including `cloudtrail.delete_trail`, `kms.schedule_key_deletion` and `organizations.leave_organization` — `set_safety_mode`
- Profiles listed and selected, with SSO supported, and the active account, region and identity reported — `list_profiles`, `select_profile`, `get_account_info`
- Resources found across every service by tag or name, rather than one service at a time — `discover_resources`
- The relationships that break things: what a resource depends on, and what would break if you changed or deleted it — `map_dependencies`, `impact_analysis`
- An automated troubleshooting pass on a failing Lambda, a slow load balancer or a security alert — `investigate_incident`
- Cost work built in: idle EC2, RDS, EBS and Elastic IP resources found, EC2 rightsizing suggested, spend broken down by service or tag, and a deployment's cost projected before you make it — `find_idle_resources`, `get_rightsizing_recommendations`, `get_cost_breakdown`, `project_costs`
- AWS reference material without leaving the session: documentation searched, a built-in knowledge base queried, service best practices and default quotas retrieved — `search_docs`, `get_aws_knowledge`, `get_best_practices`, `get_service_limits`
- LocalStack treated as an environment rather than a special case: switch to it, check it is reachable, and diff resources against production — `list_environments`, `switch_environment`, `get_environment_info`, `check_localstack`, `compare_environments`
- Multi-account work through STS: assume a role in another account, list configured accounts and switch the active one — `assume_role`, `list_accounts`, `switch_account`
- Conversation memory so follow-ups work: recent resources kept in context, and aliases like `prod-db` defined and listed — `get_context`, `set_alias`, `list_aliases`
- Automatic pagination, so a list does not silently stop at the first page
AWS credentials already configured on the machine — `~/.aws/credentials` or `~/.aws/config`; for SSO profiles run `aws sso login` first. `AWS_PROFILE` selects the profile and `AWS_DEFAULT_REGION` the region. Python 3.11+. The published package is `aws-sage-mcp` (1.0.4 in server.json); the repository installs as `aws-sage` (1.0.0 in pyproject) with `pip install .` and runs as `python -m aws_sage.server`. A Docker image mounts `~/.aws` read-only for container isolation. `AWS_SAGE_SAFETY_MODE` defaults to `read_only`, and `AWS_SAGE_LOCALSTACK_ENABLED`, `AWS_SAGE_LOCALSTACK_HOST` and `AWS_SAGE_LOCALSTACK_PORT` point it at LocalStack.
One command plus a key — pip install git+https://github.com/arunsanna/aws-sage.git, then supply credentials
