Skip to main content
BlogCloud

AWS MCP Server in Claude Code: OAuth, SigV4 and IAM Scoping

How to connect Claude Code to the managed AWS MCP Server with OAuth or the MCP Proxy for AWS, and scope IAM so an agent cannot delete what it can read.

Matthews Wong

Software Engineer

October 202612 min read
AWS MCP Server in Claude Code: OAuth, SigV4 and IAM Scoping

Key Takeaway

The AWS MCP Server, generally available since 6 May 2026, lets Claude Code call AWS through your own IAM permissions. Connect with direct OAuth for a single account, or the MCP Proxy for AWS for SigV4, multi-account and read-only use. Scope it with the aws:ViaAWSMCPService and aws:CalledViaAWSMCP condition keys, because the old aws-mcp IAM actions no longer have any effect.

I went into the AWS MCP Server expecting one fixed fact: Claude Code only speaks OAuth 2.1, AWS authenticates with SigV4, so every setup needs a local proxy in the middle. That is exactly what the general availability post says. It is also no longer the whole story, and a setup guide that stops there sends you to install software you may not need.

This post is a close reading of the AWS pages as they stand on 17 October 2026: the GA announcement, the user guide for setup, OAuth, multi-profile access and CloudTrail, the IAM pages and the proxy repository. I did not run this against an AWS account, so every command and policy below is lifted from those pages or labelled as my own illustration. The question I care about is the one the setup pages skip: how do you stop a read-capable agent from becoming a master key?

What the AWS MCP Server is, and what changed since GA

The AWS News Blog announced general availability on 6 May 2026. At launch the server was hosted in US East (N. Virginia) and Europe (Frankfurt) and could make API calls to any Region. The post states there is no additional charge for the server itself, only for the AWS resources you create and any data transfer. The current setup page lists eight endpoint Regions, among them Singapore, Sydney, Tokyo, London and Ireland, each with its own URL of the form https://aws-mcp.REGION.api.aws/mcp.

The GA post describes a call_aws tool that can run over 15,000 AWS API operations with your existing IAM credentials, and the Security Blog still refers to aws___call_aws. The tools page of the user guide that I read today lists something different: aws___run_script, aws___get_presigned_url and aws___get_tasks as the API tools, plus aws___retrieve_skill, aws___search_documentation, aws___read_documentation, aws___list_regions and aws___get_regional_availability as knowledge tools. It does not mention call_aws at all. I cannot tell from the pages whether the tool was renamed, folded into run_script or simply left out of the guide, so check the tool list your own client shows before you write any policy that assumes a tool name.

Two details from the GA post matter for security. The run_script tool executes short Python in a server-side sandbox that inherits your IAM permissions and has no network access. And skills, the curated guidance from AWS service teams that replaced Agent SOPs, are guidance rather than extra permissions. Nothing in the toolset grants access you do not already hold, which is the whole point and also the whole risk: the agent can do whatever the identity behind it can do.

The premise that expired: OAuth only, so you need a proxy

The GA post explains the proxy this way: the MCP specification only supports OAuth 2.1, AWS authenticates with IAM SigV4, so an open source MCP Proxy for AWS runs on your machine and bridges the two. Its example installs the proxy with uvx, pinned to mcp-proxy-for-aws version 1.6.0, and its notes say to check the latest version on the repository. For a developer starting from that post in May, the proxy was the only road to Claude Code.

The user guide now documents a second road. AWS Sign-in acts as the OAuth authorization server, and OAuth-compatible clients, Claude Code among them, connect to the server URL directly with no local proxy. The Claude Code command is a single line. The IAM principal needs two sign-in actions, signin:AuthorizeOAuth2Access and signin:CreateOAuth2Token, which the managed policy AWSMCPSignInOAuthAccessPolicy bundles. Interactive access tokens last one hour, and refresh tokens, which are single-use and rotated, last up to 12 hours.

So the accurate framing is a choice, not a workaround. The proxy has not become obsolete: the setup page points terminal and IDE agents such as Claude Code, Kiro and Codex at the SigV4 option, and its decision guide keeps the proxy as the pick in five situations. I dropped the idea that Claude Code requires the proxy, because the page I read contradicts it.

OAuth or SigV4 proxy: picking one for Claude Code

AWS publishes a decision guide in the setup page. I reshaped it into a table and added what each choice costs you, using only facts from the same pages.

Your situationPickWhat it costs you
You want to start without uvx, the AWS CLI or local credentialsOAuthThe role needs signin:AuthorizeOAuth2Access and signin:CreateOAuth2Token; an organisation can restrict exactly those
Your client only supports remote MCP serversOAuthEach session is bound to one IAM role, so changing account means authenticating again
The agent must reach several AWS accounts in one sessionSigV4 proxyYou run a local process, and need mcp-proxy-for-aws 1.6.0 or later for profile switching
You want write-capable tools hidden from the agent entirelySigV4 proxyThe read-only switch lives in your local config, the proxy flag --read-only
Your organisation limits the two sign-in permissionsSigV4 proxyExpired credentials become the common failure; aws login rotates them every 15 minutes for sessions up to 12 hours
You want a default Region for the whole sessionSigV4 proxySet it with --metadata AWS_REGION=...; without it, operations default to us-east-1

Below are both setups as the user guide gives them. One trade-off is worth stating plainly. The documented proxy command uses mcp-proxy-for-aws-cli at latest, so each start runs whatever release is newest, while the GA post pinned a version. The proxy repository recommends the -cli package because it pins the full dependency tree. I would pin an exact release once you have tested one, because a proxy that signs every request with your credentials is the last thing to float.

# Option A: direct OAuth. One IAM role needs the two signin actions,
# which the AWS managed policy bundles.
aws iam attach-role-policy \
  --role-name MyRole \
  --policy-arn arn:aws:iam::aws:policy/AWSMCPSignInOAuthAccessPolicy

claude mcp add aws-mcp https://aws-mcp.us-east-1.api.aws/mcp --transport http
# The first tool call opens a browser at AWS Sign-in. The access token lasts
# 1 hour and is refreshed for up to 12 hours before you sign in again.

# Option B: SigV4 through the MCP Proxy for AWS. Needs the AWS CLI 2.32.0+
# and uv. The endpoint Region picks the server; AWS_REGION in --metadata picks
# the default Region for operations (without it, operations default to us-east-1).
aws login
aws sts get-caller-identity          # prove the credentials work first
claude mcp add-json aws-mcp '{"type":"stdio","command":"uvx","args":["mcp-proxy-for-aws-cli@latest","https://aws-mcp.us-east-1.api.aws/mcp","--metadata","AWS_REGION=us-west-2"],"env":{}}'

IAM: there are no MCP permissions to grant, only keys to deny on

The IAM page is blunt: the server defines no IAM actions, resources or service-specific condition keys of its own. It authenticates your request with SigV4, adds two standard condition context keys, and forwards the call; the downstream service then authorizes it with your existing policies. Using the server therefore needs no MCP-specific permission, only the permissions you would need for a direct API call.

The two keys are aws:ViaAWSMCPService, a Boolean that is true for any request through an AWS managed MCP server, and aws:CalledViaAWSMCP, a string holding the server's service principal. The documented example values are aws-mcp.amazonaws.com for this server, eks-mcp.amazonaws.com for the EKS server and ecs-mcp.amazonaws.com for the ECS server. The first key switches off all managed MCP servers at once; the second targets one.

// Wrong: written for the preview. These aws-mcp actions are deprecated and
// have no effect, so this Deny matches nothing and nothing tells you.
{
  "Effect": "Deny",
  "Action": ["aws-mcp:CallReadWriteTool"],
  "Resource": "*"
}

// Right: key the Deny on the context keys the server adds to every
// forwarded request. aws:ViaAWSMCPService is true for any AWS managed MCP
// server; aws:CalledViaAWSMCP names the one server by its service principal.
{
  "Sid": "DenyDeleteWhenAccessedViaMCP",
  "Effect": "Deny",
  "Action": ["s3:DeleteObject", "s3:DeleteBucket"],
  "Resource": "*",
  "Condition": {
    "StringEquals": { "aws:CalledViaAWSMCP": "aws-mcp.amazonaws.com" }
  }
}

The first snippet above is the trap, and it is the most important thing in this post. During the preview, the server required the actions aws-mcp:InvokeMcp, aws-mcp:CallReadOnlyTool and aws-mcp:CallReadWriteTool. AWS now states they are no longer required and have no effect, in Allow and in Deny statements alike. The second snippet is the AWS-documented replacement.

Scoping so the agent is not a master key

A condition key lets one identity behave differently depending on whether a human or an agent is calling. AWS shows the pattern with a policy that allows S3 reads and denies s3:DeleteObject and s3:DeleteBucket when the request arrives through the server. That is a Deny list, and a Deny list only covers what you thought of. My own view, which the AWS pages do not state, is to layer controls so that no single list decides your exposure. The table below is my arrangement of the controls the pages describe.

LayerWhere it livesWhat it stopsWhat it misses
Narrow role for the agentIdentity policy on the role the agent assumesEvery action you did not allow, via both OAuth and SigV4Nothing within the allowed actions; a read role can still read secrets
Deny on aws:CalledViaAWSMCPIdentity policy or permission boundaryListed actions, only when they arrive through the server; humans keep themAny action you forgot to list
SCP on aws:ViaAWSMCPServiceOrganization or OUAll managed MCP access in an OU, however a role is writtenIt is all or nothing, so it does not give a sandbox account its own rules
Proxy --read-onlyLocal proxy arguments in the MCP client configHides tools that may need write permissions from the agentIt is not an IAM control; the credentials behind it are unchanged
Client approval rulesMCP client hooks and permission rulesA human sees a production call before it runsApproval fatigue; AWS lists it as an extra gate, not a boundary

The first policy below is my illustration of layer 1, the others are from AWS. The multi-profile page adds the advice I would follow for several accounts: make a read-only profile the default, because the first listed profile is what the proxy signs with when the agent names none, and make write-capable profiles an explicit choice. Only profiles declared at startup are reachable, so the agent cannot wander into the rest of your AWS config file.

// Layer 1 (my own illustration, not an AWS sample): the role the agent
// assumes allows reads only. Anything not listed is denied by default.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AgentReadOnly",
      "Effect": "Allow",
      "Action": ["ec2:Describe*", "s3:ListBucket", "s3:GetObject", "logs:FilterLogEvents"],
      "Resource": "*"
    }
  ]
}

// Layer 3: an SCP (or identity policy) that shuts every AWS managed MCP
// server out of an OU. This one is copied from the AWS user guide.
{
  "Sid": "DenyAllActionsViaMCP",
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": { "Bool": { "aws:ViaAWSMCPService": "true" } }
}

# Layer 4: hide write-capable tools at the proxy. Sign with a read-only
# profile first, and name any extra profiles you want the agent to reach.
uvx mcp-proxy-for-aws-cli@latest https://aws-mcp.us-east-1.api.aws/mcp \
  --read-only --profile prod-readonly dev

Test the Deny before you trust it. Assume the role, call a listed action once through the server and once through the CLI, and confirm only the MCP call is refused. Given that the retired aws-mcp actions fail silently, a Deny that you never saw fire is a Deny you do not have.

Where it goes wrong: failures and trade-offs

Most of the risk here comes from rules that look correct and do nothing, rather than from the server itself.

A preview-era Deny on aws-mcp:CallReadWriteTool, aws-mcp:CallReadOnlyTool or aws-mcp:InvokeMcp blocks nothing today. AWS says these actions no longer have any effect, so an organisation that wrote its guardrails in the preview has no guardrail now. Search your SCPs and permission boundaries for the aws-mcp: prefix and replace each hit with a condition-key Deny.

Other traps I found in the pages, in the order I would worry about them:

  • Revoking access is not instant. Revoking a refresh token stops new access tokens, but existing ones live up to an hour. For immediate containment, AWS says to deny requests by the aws:SignInSessionArn condition key.
  • Changing an IAM policy on the principal revokes its OAuth refresh tokens automatically, which is useful when tightening a role but means sessions end without warning.
  • The OAuth client list is closed. Only approved agents can register through Dynamic Client Registration, and only public redirect URIs work, so an internal tool of your own cannot just register.
  • Documentation has drifted already: the tool name in the GA post is absent from the current tool page. Policies written against tool names, rather than API actions, will rot.

The trade-off underneath it all is convenience against containment. OAuth is the shortest route to a working agent, while the SigV4 proxy buys read-only mode, profile control and a fixed default Region at the price of a process to keep updated. I would take the proxy for anything near production and OAuth for a sandbox account, but that is a judgement, not something AWS prescribes.

What you can see afterwards: CloudTrail and metrics

The user guide says CloudTrail captures all calls for authenticated tools. A call to the read-write tool appears as an event with eventSource aws-mcp.amazonaws.com, eventName CallReadWriteTool and eventType AwsMcpEvent, with the exact request parameters copied in. Note that the guide classifies the entry as a data event, so a default trail may not hold it until you configure one to; I did not verify what Event history shows. With OAuth, Sign-in also records AuthorizeOAuth2Access and CreateOAuth2Token, and later API calls carry the aws:SignInSessionArn context so you can tie activity to the sign-in.

// Fields from the AWS CloudTrail user guide for an MCP tool call. The entry
// is a data event, so check your trail records them rather than assuming.
{
  "eventCategory": "Data",
  "eventType": "AwsMcpEvent",
  "eventSource": "aws-mcp.amazonaws.com",
  "eventName": "CallReadWriteTool",
  "requestParameters": { "method": "tools/call", "params": { } },
  "mcpEventDetails": { "mcpServerName": "aws-mcp.us-east-1.api.aws" }
}
// The tool name is logged without the client prefix: your client shows
// aws___retrieve_skill, CloudTrail logs retrieve_skill.

The GA post adds CloudWatch metrics in the AWS-MCP namespace that separate agent calls from direct human calls. I could not find the metric names on the pages I read, so I am not listing any. The Security Blog recommends using CloudTrail to see what agents actually do, then tightening policies from that evidence, and starting restrictive before loosening.

What to do on Monday

A short sequence that follows from the pages above. Do it in a sandbox account first.

  1. Search every SCP, boundary and role policy for the aws-mcp: prefix, and replace any Deny with the aws:ViaAWSMCPService or aws:CalledViaAWSMCP condition key.
  2. Create a narrow read-only role for the agent, and make that the identity Claude Code uses, not your administrator profile.
  3. Connect with OAuth for a single sandbox account, or with the proxy, pinned to a tested version, if you need profiles, read-only mode or a default Region.
  4. List the tools your client actually shows and read their names. Do not assume call_aws exists.
  5. Call one listed action through the server and one through the CLI. Confirm that only the first is denied, then find both in CloudTrail.

Only when all five hold should the same server be pointed at a role with write access, and then only through a Deny list you have seen refuse something.

The AWS MCP Server does not add permissions, it exposes the ones you already have to an agent, so the work is shrinking the identity and proving the Deny fires. Treat the proxy as a choice rather than a requirement, never trust an aws-mcp action in a policy, and read the tool list your client shows rather than the one in a blog post, including this one.

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

Does Claude Code need the MCP Proxy for AWS to use the AWS MCP Server?

No longer. The AWS user guide documents a direct OAuth connection for Claude Code with one command, claude mcp add aws-mcp https://aws-mcp.us-east-1.api.aws/mcp --transport http. The proxy is still the documented route when you need several accounts in one session, a read-only mode, a default Region or your organisation restricts the OAuth sign-in permissions.

What does the AWS MCP Server cost?

The GA announcement states there is no additional charge for the server itself. You pay for the AWS resources your agent creates and for any applicable data transfer. Check the current AWS pages before relying on this, because pricing statements can change.

Which IAM permissions does the AWS MCP Server need?

None of its own. The server defines no IAM actions, and the old aws-mcp:InvokeMcp, CallReadOnlyTool and CallReadWriteTool actions are deprecated and have no effect. Your agent needs the same permissions on the downstream service as a direct API call would, plus signin:AuthorizeOAuth2Access and signin:CreateOAuth2Token if you connect with OAuth.

How do I stop an AI agent from deleting AWS resources through the MCP server?

Add a Deny statement keyed on the aws:CalledViaAWSMCP condition key with the value aws-mcp.amazonaws.com, listing the destructive actions such as s3:DeleteObject. Humans calling the same actions directly are unaffected. Because a Deny list only covers what you list, also give the agent a narrow role and test that the Deny actually refuses a call.

Can the AWS MCP Server work across multiple AWS accounts?

Yes, but only with SigV4 through the MCP Proxy for AWS, version 1.6.0 or later. You start the proxy with several profiles, the first being the default, and the agent can name another per call. OAuth binds a session to one IAM role, so switching accounts there means authenticating again.