AWS — Official AWS MCP Server
Connect Willow to the AWS MCP Server, AWS's managed remote MCP server, to give your AI assistants access to your AWS account: describing resources, reading configuration, searching AWS documentation, and running AWS API calls through the server's sandboxed run_script tool.
The server is available in two regions:
- US East (N. Virginia):
https://aws-mcp.us-east-1.api.aws/mcp - Europe (Frankfurt):
https://aws-mcp.eu-central-1.api.aws/mcp
AWS recommends the AWS MCP Server over the older awslabs.aws-api-mcp-server and aws-knowledge-mcp-server packages. If you already connected either of those to Willow, remove them after adding this server, so agents don't see two overlapping sets of AWS tools.
How authentication works
AWS supports two ways to authenticate to the AWS MCP Server: OAuth through AWS Sign-In, or AWS Signature Version 4 (SigV4). Willow uses SigV4. You store an IAM access key in the Vault, and Willow signs each request with it in the gateway. This does the same job as AWS's MCP Proxy for AWS, without running a local process. The secret key never leaves Willow; only the signature is sent to AWS.
The AWS MCP Server calls AWS APIs as the IAM user you create, so that user's IAM policies decide what your agents can and can't do. Choosing those policies is the most important part of the setup. See Example policies.
Prerequisites
- An AWS account and permission to create IAM users, policies, and access keys
- A Willow admin account with access to Security Center → Vault
Steps
1. In AWS — create an IAM user for Willow
Create a dedicated IAM user, rather than reusing one that people or other systems use. The examples below name it willow-aws-mcp.
In the AWS console:
- Open the IAM console and go to Users → Create user.
- Enter a User name. Leave Provide user access to the AWS Management Console unchecked; the user only needs an access key.
- On Set permissions, choose Attach policies directly and select the AWS managed policies you want, for example
ViewOnlyAccess. You can add custom policies after the user exists. - Click Next, then Create user.
- Add any custom policies from Example policies. See Applying a custom policy.
- Open the user, go to the Security credentials tab, and under Access keys click Create access key.
- Choose Third-party service as the use case, confirm, and click Next, then Create access key.
- Copy the Access key and Secret access key, or click Download .csv file. AWS shows the secret only once.
With the AWS CLI:
aws iam create-user --user-name willow-aws-mcp
# Attach an AWS managed policy, for example ViewOnlyAccess
aws iam attach-user-policy \
--user-name willow-aws-mcp \
--policy-arn arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
# Attach any custom policies (see "Applying a custom policy" below)
aws iam create-access-key --user-name willow-aws-mcp
Copy AccessKeyId and SecretAccessKey from the output of create-access-key.
2. In Willow — store the access key in the Vault
- Go to Security Center → Vault and click Add Secret.
- Add two secrets:
AWS_ACCESS_KEY_IDwith the access key IDAWS_SECRET_ACCESS_KEYwith the secret access key
3. In Willow — add the AWS MCP Server
-
In the sidebar, go to MCP Servers under the Build section.
-
Click + Add MCP Server, hover over Custom MCP, and select Configure.
-
Enter a Name (for example,
AWS) and a Slug. -
Switch to JSON and paste:
{"type": "http","url": "https://aws-mcp.us-east-1.api.aws/mcp","awsSigV4": {"accessKeyId": "{{vault.AWS_ACCESS_KEY_ID}}","secretAccessKey": "{{vault.AWS_SECRET_ACCESS_KEY}}"}}For the Frankfurt endpoint, change the URL to
https://aws-mcp.eu-central-1.api.aws/mcp. -
Leave Advanced Options authentication empty; the
awsSigV4block handles it. -
Click Create Integration.
4. Test the connection
Ask your AI assistant:
- Which AWS identity am I using? The answer should be the
willow-aws-mcpuser. This confirms that signing works, because the assistant has to callsts:GetCallerIdentityas that user. - An action your policies should block, such as List my KMS keys. It should fail with an access denied error.
A question like What AWS Regions are available? isn't a useful test. The server answers region and documentation questions without checking credentials, so it succeeds even when authentication is broken.
Example policies
The policies below are examples to adapt, not a required setup. Pick the ones that match what your agents need, combine them, and narrow them further for your account. Whatever you attach, the MCP server can do exactly what the IAM user can do.
Two IAM rules to keep in mind when combining policies:
- An action is allowed only if some policy allows it.
- An explicit
Denyalways wins over anyAllow, which makes deny policies a reliable guardrail on top of broad read access.
Applying a custom policy
Every JSON example below can be applied the same way. Save it to a file, for example policy.json.
In the AWS console, as an inline policy for this user only:
- In the IAM console, open Users →
willow-aws-mcp→ Permissions. - Click Add permissions → Create inline policy.
- Switch the Policy editor to JSON, paste the policy, and click Next.
- Enter a Policy name and click Create policy.
To reuse a policy across users, create it under Policies → Create policy instead, then attach it from the user's Add permissions → Attach policies directly.
With the AWS CLI:
# Inline policy on this user only
aws iam put-user-policy \
--user-name willow-aws-mcp \
--policy-name <policy-name> \
--policy-document file://policy.json
# Or a reusable managed policy
aws iam create-policy \
--policy-name <policy-name> \
--policy-document file://policy.json
aws iam attach-user-policy \
--user-name willow-aws-mcp \
--policy-arn arn:aws:iam::<account-id>:policy/<policy-name>
Example 1: Read-only access with an AWS managed policy
AWS maintains two managed policies for read-only access. Attach one of them instead of writing your own allow list.
| Policy | What it allows |
|---|---|
ViewOnlyAccess | Lists and describes resources and their configuration. Doesn't read data inside them. |
ReadOnlyAccess | Everything ViewOnlyAccess allows, plus reading data: S3 objects, DynamoDB items, CloudWatch Logs, and more. |
ViewOnlyAccess is the safer starting point for an agent. Use ReadOnlyAccess when agents need to read data, and pair it with Example 2.
aws iam attach-user-policy \
--user-name willow-aws-mcp \
--policy-arn arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
In the console, choose Attach policies directly and search for ViewOnlyAccess.
Example 2: Block secrets and encryption keys
Denies KMS and Secrets Manager entirely, plus the other places secrets usually live: Parameter Store values, Lambda environment variables, and EC2 Windows passwords. It also denies creating access keys and assuming other roles, so the user can't step outside its own permissions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyKmsAndSecretsManager",
"Effect": "Deny",
"Action": ["kms:*", "secretsmanager:*"],
"Resource": "*"
},
{
"Sid": "DenyOtherPlacesSecretsLive",
"Effect": "Deny",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"ssm:GetParameterHistory",
"lambda:GetFunction",
"lambda:GetFunctionConfiguration",
"ec2:GetPasswordData",
"iam:CreateAccessKey",
"sts:AssumeRole"
],
"Resource": "*"
}
]
}
Example 3: Scoped read access for incident investigation
An allow list for an agent that investigates incidents: metrics, alarms, logs, and the compute resources behind them, and nothing else. Use it instead of Example 1 when you want a narrow scope.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadMonitoring",
"Effect": "Allow",
"Action": [
"cloudwatch:Describe*",
"cloudwatch:Get*",
"cloudwatch:List*",
"logs:Describe*",
"logs:FilterLogEvents",
"logs:GetLogEvents",
"logs:StartQuery",
"logs:GetQueryResults"
],
"Resource": "*"
},
{
"Sid": "ReadCompute",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ecs:Describe*",
"ecs:List*",
"eks:Describe*",
"eks:List*",
"elasticloadbalancing:Describe*",
"autoscaling:Describe*"
],
"Resource": "*"
}
]
}
Application logs can contain tokens and personal data. Consider narrowing the logs: actions to specific log groups by replacing "Resource": "*" with their ARNs, for example arn:aws:logs:us-east-1:<account-id>:log-group:/ecs/my-service:*.
Example 4: Limit agents to specific regions
Denies any regional call outside the listed regions. Global services such as IAM and STS are excluded, because they don't run in a single region.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideApprovedRegions",
"Effect": "Deny",
"NotAction": [
"iam:*",
"sts:*",
"organizations:*",
"route53:*",
"cloudfront:*",
"support:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "eu-west-1"]
}
}
}
]
}
Example 5: Guardrails that apply only through the MCP server
The AWS MCP Server adds two condition keys to every call it makes on your behalf:
aws:ViaAWSMCPServiceistruefor any request through an AWS managed MCP server.aws:CalledViaAWSMCPnames the specific server,aws-mcp.amazonaws.comfor this one.
Direct calls don't carry these keys, so a deny that checks them affects agents but not people or scripts using the same identity. This is useful when the identity isn't dedicated to Willow, or as a second layer on top of the other examples. This example blocks destructive actions when they come through the MCP server:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyDestructiveActionsViaMcp",
"Effect": "Deny",
"Action": [
"ec2:TerminateInstances",
"ec2:DeleteVolume",
"ec2:DeleteSnapshot",
"s3:DeleteBucket",
"s3:DeleteObject",
"rds:DeleteDBInstance",
"rds:DeleteDBCluster",
"dynamodb:DeleteTable",
"lambda:DeleteFunction",
"cloudformation:DeleteStack",
"iam:Create*",
"iam:Delete*",
"iam:Attach*",
"iam:Put*"
],
"Resource": "*",
"Condition": {
"Bool": { "aws:ViaAWSMCPService": "true" }
}
}
]
}
To target only the AWS MCP Server rather than every AWS managed MCP server, replace the condition with "StringEquals": { "aws:CalledViaAWSMCP": "aws-mcp.amazonaws.com" }.
Example 6: Organization-wide guardrail with a service control policy
If you use AWS Organizations, a service control policy (SCP) applies to every identity in the accounts it targets, including users created later. This SCP blocks secrets access through any AWS managed MCP server across those accounts:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenySecretsViaMcp",
"Effect": "Deny",
"Action": ["kms:*", "secretsmanager:*", "ssm:GetParameter*"],
"Resource": "*",
"Condition": {
"Bool": { "aws:ViaAWSMCPService": "true" }
}
}
]
}
In the AWS console: open AWS Organizations → Policies → Service control policies (enable them if prompted), click Create policy, paste the JSON, and click Create policy. Then open the policy, go to Targets → Attach, and choose the accounts or organizational units.
With the AWS CLI, from the organization's management account:
aws organizations create-policy \
--name DenySecretsViaMcp \
--type SERVICE_CONTROL_POLICY \
--description "Block secrets access through AWS managed MCP servers" \
--content file://scp.json
aws organizations attach-policy \
--policy-id <policy-id> \
--target-id <account-id-or-ou-id>
Suggested combinations
| Goal | Policies |
|---|---|
| Let agents explore the account safely | Example 1 (ViewOnlyAccess) + Example 2 |
| Let agents read data, but not secrets | Example 1 (ReadOnlyAccess) + Example 2 |
| Incident investigation in your production regions | Example 3 + Example 2 + Example 4 |
| Use an identity that people or scripts also use | That identity's existing policies + Example 5 |
| A guardrail that holds even if someone changes the user's policies | Any of the above + Example 6 |
Checking a policy before you rely on it
Use the IAM policy simulator to see how AWS evaluates specific actions for the user. Open the IAM policy simulator, select the willow-aws-mcp user, and choose the actions to test, or run:
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::<account-id>:user/willow-aws-mcp \
--action-names kms:Decrypt secretsmanager:GetSecretValue ec2:DescribeInstances
For Examples 1 through 4, you can also run the same calls with the user's access key from your terminal. Policies that check aws:ViaAWSMCPService or aws:CalledViaAWSMCP (Examples 5 and 6) only apply to requests made through the MCP server, so test those by asking your assistant.
Configuration reference
| Field | Required | Description |
|---|---|---|
accessKeyId | Yes | IAM access key ID. Use a vault reference. |
secretAccessKey | Yes | IAM secret access key. Use a vault reference. |
sessionToken | No | Session token, for temporary credentials. Temporary credentials expire, so prefer an IAM user's access key. |
region | No | Signing region. Defaults to the region in the URL, for example us-east-1 for aws-mcp.us-east-1.api.aws. |
service | No | Signing service name. Defaults to the first part of the host, aws-mcp. |
region and service can only be inferred from <service>.<region>.api.aws hosts. Other AWS managed MCP servers on that pattern, such as https://eks-mcp.us-west-2.api.aws/mcp, work with the same config. For any other host, set both explicitly.
The signing region is where the MCP server runs, not where your resources are. AWS's own proxy can set a default region for AWS operations; Willow doesn't send one, so operations default to us-east-1. Name the region in your prompt, for example List EC2 instances in eu-west-1, to work elsewhere.
Troubleshooting
"Authentication failed: Unable to verify your user identity"
AWS received the request without a signature. Check that the configuration has an awsSigV4 block. Access keys passed as headers are never read by AWS.
"awsSigV4.secretAccessKey references a vault secret that doesn't exist or has no value"
The vault reference didn't resolve. Check that the secret name in the configuration matches the name in Security Center → Vault exactly.
"Your AWS credentials are invalid or have expired" or UnrecognizedClientException
AWS doesn't recognize the key. It may have been deactivated or deleted, or the IAM user was deleted. Create a new access key, update the vault secrets, and see MCP Connection Failed After Secret Update.
ExpiredTokenException
The configuration uses temporary credentials (sessionToken) that have expired. Switch to an IAM user's access key, which doesn't expire, or refresh all three values.
"Credential should be scoped to correct service: 'aws-mcp'" or InvalidSignatureException
The signature doesn't match. Usually a service or region override doesn't match the endpoint; remove both and let Willow infer them from the URL. SigV4 also requires the signing clock to be within five minutes of AWS's.
A tool call fails with "no identity-based policy allows the … action"
No policy on the IAM user allows that action. If agents should be able to do it, add a policy that allows it.
A tool call fails with "explicit deny in an identity-based policy"
A deny policy blocked the action, as intended. The error names the policy that denied it.
Notes
- The AWS MCP Server is published by AWS. Willow passes its tools through without modifying their behavior. To hide specific tools from agents, see Manage Tools.
- AWS's proxy has a read-only mode that hides write-capable tools. Willow doesn't use it, so rely on the IAM user's policies to block writes.
- Every call appears in AWS CloudTrail under the IAM user.
- AWS also offers OAuth sign-in for this server, but AWS Sign-In rejects Willow's callback URL, so Willow uses SigV4 with an access key.
- All of your organization's assistants share one IAM identity per MCP server. For separate permissions per team, create a separate IAM user and MCP server for each.