DEV Community

Cover image for AWS MCP Server: which one to use, when, and how to set it up (now that AWS recommends just one)
will peixoto for AWS Community Builders

Posted on • Originally published at willpeixoto.dev

AWS MCP Server: which one to use, when, and how to set it up (now that AWS recommends just one)

Knowledge MCP vs the managed AWS MCP Server, IAM, and the setup in Claude Code, the Claude app, and Kiro without pasting a key into .env.

🇧🇷 Também disponível em português: AWS MCP Server: qual usar, quando e como configurar

Let me tell you a scene. I bet you've lived it.

It's 11pm, you're coding with an AI sitting right next to you. You ask it something and it swears the thing exists: it makes up a service, a name that sounds a lot like something you've built before, even an implementation it promises works, with the full how-to. And you think: huh, didn't know that one, let me check the docs because it makes total sense. And bang, you find out it was hallucinating. It was writing Lambda code calling an AWS service from a function that doesn't exist, wiring up the DynamoDB table, building the IaC, the whole thing. Then it asks to "take a look at your account's current config" to validate the names, and you hit the wall everyone hits.

The agent, besides hallucinating, has no access to your account. It can't see your resources, it has no idea what's actually there. So it does what it does best: it's creative, it's proactive, and it invents something to make you happy. To it, that thing makes sense to exist, so it assumes it exists. The little guy doesn't even blush: it hands you an ARN that doesn't exist, picks a region you don't use, and guesses a table name. There it goes. It's doing exactly what it was built to do, which is make you happy.

And you, tired of fighting with it and just wanting to wrap up, do what? You paste an access key into a .env so it can "just see the account for a second" and give you everything right, with the real names. Who's never done that?

And it's all fine, except for one detail: you forget you did it. And bang, the .env went along in the commit. It's already in the git history, alerts firing everywhere, the usual mess. The key is exposed now. And that's also how your agent, in that moment where it seems to want to punish you or decided to be a little too proactive, gets real access to your account and, who knows, decides to delete the wrong stack. Or it's just the surprise bill of forty bucks in a single day, which turns into a much worse number when nobody's watching. I've been through this. You probably have too.

The good news is that AWS solved this. Actually, it solved it two different ways, with names so similar they confuse a lot of people. This post is the map I wish I'd had: what the two are, which pain each one kills, and when and how to use each. Let's go.

Freshness note: the MCP world moves fast. I wrote this guide in June 2026 and already had to update it in July 2026, when the connection flow changed (the version you're reading has direct OAuth). I'll do my best to keep it current as things ship, but if something doesn't match the screen in front of you, check the official docs and tell me in the comments so I can fix it.

What you'll walk away knowing

So you don't get lost, here's what we cover:

  • The difference between the two AWS MCP servers and which pain each one solves
  • How to connect it in Claude Code, the Claude app, and Kiro, step by step
  • How to set up your account's IAM to grant access safely
  • When NOT to use it, and how to avoid a nasty surprise on your bill

But what is MCP, anyway?

Before talking about the servers, let's level set.

MCP (Model Context Protocol) is the "plug" your AI assistant uses to talk to the outside world: tools, data and services. Anthropic created it, it's under open governance now, and over the last year every assistant worth using (Claude Code, Kiro, Cursor) started speaking MCP.

Want an easy analogy? Think about the API. The API is what lets two applications talk to each other. MCP is the same idea, just for the agent: it's what lets the AI talk to any tool without you having to build a custom integration for every single system. MCP connects the agent to the system through a standard everyone agreed to use. And that's the nice thing about a standard: you learn it once and it works for any tool and any client. So if you want to give an AI access to your system, this is the path to follow.

And here's something that makes life a lot easier: for most cases, you don't even need to build your own MCP server. You can build one, sure (on Lambda, on Fargate, whatever you prefer), and AWS even has an official guidance for that if that's your case. But AWS already runs managed servers ready to go, so a lot of the time you just plug in and use it. Building your own makes sense when the goal is different: exposing your own internal system (an API, a runbook, an alert) to the agent.

The two AWS MCP servers

Yep, there are two. And the names don't help at all. Here's everything in one table, then I break down each one:

AWS Knowledge MCP Server AWS MCP Server (managed, GA)
What it solves "My agent hallucinates AWS APIs, ARNs and service names." "My agent needs to see or act on my account, without me leaking a key."
What it accesses Only AWS docs and knowledge (read-only) Docs + real services in your account (authenticated)
Credentials None. You don't even need an AWS account. AWS browser sign-in (OAuth) or AWS CLI (SigV4)
Audit Not applicable CloudTrail + CloudWatch
Use it when You want correct syntax, current docs, regional availability You want the agent inspecting or operating real infra
Risk if misused Basically zero Real. It's your account. Least-privilege matters.

If you keep one sentence from this post, keep this one:

One server gives your agent knowledge. The other gives it hands.

Figuring out which problem you actually have is half the battle.

Want another analogy? The Knowledge server is the guru: that friend who memorized the entire AWS documentation and clears up your doubt on the spot. The managed one is the doorman checking badges: it lets you into the account for real, but it stands there checking and only opens the doors IAM authorized. Name doesn't match the badge? You don't get in.

Where does this run? The AWS MCP Server is remote, and what connects to it is the MCP client: Claude Code, the Claude app (Desktop and claude.ai), Kiro, Cursor, or your own agent's code (Strands, SDK). That holds even with inference running on Bedrock, because the client is the application, never the model. A production agent on AgentCore, though, typically consumes tools through the AgentCore Gateway (which also speaks MCP) or your own MCP server. That production scenario is a topic for another post in this series.

Server #1: AWS Knowledge MCP Server

What this server does is simple: it's remote, fully managed, and it gives the model structured access to the official docs, always current. And that "current" is the point. What the model knows on its own stops at its training date, so it has no clue about what came after and ends up guessing. AWS keeps this server in sync, so it becomes your source of truth: it searches the docs, returns the page as clean markdown, checks whether a service exists in a region, and lists the current regions. Read-only, it doesn't write or touch the account.

Why is it almost a no-brainer to turn on? Because there's no credential, and no AWS account needed. Nothing to protect, nothing to leak. The risk is basically zero and the payoff is the agent stops guessing and starts citing the real docs before it spits out the CDK.

Use it when you're learning a service, designing the architecture you want to build and validating the idea, checking syntax, generating IaC you actually trust, or answering "is this in my region yet?" without opening the browser. Connecting is pasting a URL: add https://knowledge-mcp.global.api.aws as a remote (HTTP) server in your client and that's it, no credentials at all. With it on, the agent checks the live docs before spitting out the CDK instead of guessing from training. Hallucinated ARNs drop off a cliff. Pretty good, right?

Server #2: AWS MCP Server, the managed one (reads and operates the account)

This is the one that cures the .env shame.

The pain is different: the agent needs to see or do something in the account for real. Read the CloudWatch logs of the function that's breaking, list what's actually in the bucket, check the real schema of the DynamoDB table. The old "solution" was to hand it a long-lived credential. That's the part that keeps the security folks up at night. And honestly, it should keep you up too.

What this server does: it's remote, hosted and managed by AWS, and it gives the agent authenticated access to AWS services through a small, fixed set of tools. No local install, automatic updates, and (this part I really like) every call lands in CloudTrail. The agent doesn't get a master key. It authenticates as you, through a real auth flow, on an IAM leash.

The auth flow in plain English: there are two paths now, and the newer one is the simpler one. Today the server speaks OAuth directly. You add the URL to your client, the first tool call opens the browser on AWS Sign-in, you log in with your usual identity, done. The token lasts 1 hour and refreshes itself for up to 12. No proxy, nothing to install.

The second path is SigV4 with mcp-proxy-for-aws, an open source proxy that runs on your machine, takes your local AWS CLI credentials, and signs every call. It still exists and it has its moment: multiple accounts in the same session, read-only mode (hiding write-capable tools from the agent), a fixed default region, or an org that blocks the OAuth permissions (signin:AuthorizeOAuth2Access and signin:CreateOAuth2Token).

Either way the outcome is the same: you don't paste a key anywhere, the agent acts with your identity, and everything respects your IAM. Documentation search, by the way, needs no credentials at all.

The OAuth flow, step by step:

  1. You attach the AWSMCPSignInOAuthAccessPolicy managed policy to your role or user (once).
  2. You add the server URL to your client and fire the first call.
  3. The browser opens on AWS Sign-in, you authorize, and the client keeps the token (1 hour, auto-refresh up to 12).
  4. The server applies the context keys and forwards to the AWS service.
  5. IAM authorizes via your policy and responds.
  6. The whole call is logged to CloudTrail.

The "ohhh, got it" moment is this: ask "why did checkout-prod start throwing 500s after 2pm?" and watch the agent pull the real CloudWatch logs, cross-reference a recent deploy, and point at the actual resource. All inside what IAM allows, all auditable, with no key in any dotfile. And it works with what you already use: Claude Code, Kiro, Cursor, any MCP-compatible client.

How to connect: Claude Code, the Claude app, and Kiro

Now the practical part. The OAuth path has a single prerequisite: the identity you'll use needs the sign-in managed policy. Attach it once and forget it:

aws iam attach-role-policy \
  --role-name MyRole \
  --policy-arn arn:aws:iam::aws:policy/AWSMCPSignInOAuthAccessPolicy
Enter fullscreen mode Exit fullscreen mode

(If you use an IAM user instead of a role, it's attach-user-policy with --user-name.)

In Claude Code

One line, and that's really it:

claude mcp add aws-mcp https://aws-mcp.us-east-1.api.aws/mcp --transport http
Enter fullscreen mode Exit fullscreen mode

On the first tool call the browser opens, you log in, and the agent sees the account on an IAM leash.

There's also a second route: the aws-core plugin. On top of the AWS MCP Server pre-configured, it brings the AWS agent skills, which are ready-made instruction packs so the agent handles CDK, serverless, containers and billing tasks well. If you want the server plus that extra context in one go, install it from Anthropic's official marketplace, which Claude Code already ships with:

/plugin install aws-core@claude-plugins-official
Enter fullscreen mode Exit fullscreen mode

One detail that trips people up: this command runs inside Claude Code, in the terminal. The "Plugins" section in the Claude Desktop app is a different catalog, so don't go looking for aws-core there (in the app, the path is the connector in the next section). The steering equivalent here is a CLAUDE.md at the project root, with the same rules I show in the Kiro block below.

In the Claude app (Desktop and claude.ai)

Yes, it works in the app, no terminal needed. In Claude Desktop: Settings, Connectors, "Add custom connector", give it a name (I called mine aws-mcp) and paste the URL:

https://aws-mcp.us-east-1.api.aws/mcp?oauth=initialize
Enter fullscreen mode Exit fullscreen mode

The ?oauth=initialize suffix tells the server to kick off the OAuth flow explicitly (Cursor and Kiro IDE use the same trick). Leave the OAuth Client ID and Secret fields empty, the flow handles that. On claude.ai web it's the same URL without the suffix, in the connector settings.

Adding the AWS MCP Server as a custom connector in Claude Desktop

On the first call, the AWS authorization screen opens:

AWS Sign-in consent screen connecting the MCP client to the AWS MCP Server

Two warnings here, because I hit them first so you don't have to:

It's not the Directory connector. If you search "AWS" in Claude's connector directory, an "AWS API MCP Server" shows up. That is NOT the new managed one: it's the older aws-api-mcp-server from awslabs (look at its tools, just suggest_aws_commands and call_aws), precisely one of the servers the official docs tell you to replace. The right path is the custom connector with the URL above. And don't run both, that's the exact tool-conflict scenario AWS warns about.

Don't authorize as root. The consent screen offers "Continue with Root or IAM user" and says access follows "your existing AWS permissions". Whatever identity you use there defines the agent's blast radius. Sign in with an IAM user or a dedicated role, with the sign-in managed policy and least-privilege. Root driven by an agent is everything we don't want. And a practical red flag: if the connection worked without you attaching any policy, investigate with an aws sts get-caller-identity. Either your identity is an admin, or you signed in as root, which doesn't go through IAM at all (I fell for this one too: logged in, worked on the first try, and it was root driving the whole account).

In Kiro

In Kiro CLI (2.11 or later):

kiro-cli mcp add --name aws-mcp --url https://aws-mcp.us-east-1.api.aws/mcp
Enter fullscreen mode Exit fullscreen mode

In Kiro IDE, add it as a remote server with the ?oauth=initialize URL, or via mcp.json (per project at <root>/.kiro/settings/mcp.json, global at ~/.kiro/settings/mcp.json; when both exist, the project one wins).

But config only turns the server on, it doesn't guarantee Kiro will use it. To make it prefer these tools, create a steering file at .kiro/steering/aws-mcp.md:

---
inclusion: always
---

# Using AWS via MCP

- Before generating any AWS code or IaC (CDK, CloudFormation, SDK), validate
  service names, syntax and regional availability against the docs via the
  `aws-mcp` server (documentation search tool). Don't guess APIs or ARNs.
- To inspect real account resources (CloudWatch logs, S3 items, DynamoDB
  schema), use the same `aws-mcp` server. Never ask for or use an access key.
- Never run a destructive action (delete, scaling) without confirming first.
Enter fullscreen mode Exit fullscreen mode

inclusion: always makes that rule part of every Kiro conversation in that project.

The advanced path: SigV4 with the proxy

If you landed on one of the SigV4 cases (multi-account, read-only mode, default region, no-OAuth org), the setup asks a bit more of your local machine: AWS CLI 2.32+ signed in with aws login (credentials rotate on their own every 15 minutes, sessions up to 12 hours), uv installed, and the proxy in mcp.json:

{
  "mcpServers": {
    "aws-mcp": {
      "command": "uvx",
      "args": [
        "mcp-proxy-for-aws==1.6.2",
        "https://aws-mcp.us-east-1.api.aws/mcp",
        "--metadata", "AWS_REGION=sa-east-1"
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Pin the proxy version (your supply chain will thank you) and check PyPI for the current pin. The endpoint is regional (today us-east-1 and eu-central-1); you connect to one of them and operate on resources in whatever region you pass in AWS_REGION. Check the current list in the official docs, since this can change.

The security part you can't ignore

"Everything fails, all the time."

Werner Vogels, Amazon CTO

If there's one part not to skip, it's this one. Werner's right, and with an AI driving your account it's worth taking that literally: assume the agent will mess up sooner or later, and design for it. Giving it access to read and operate your account is as serious as it sounds, so it's worth doing carefully.

First thing: IAM is still the boss. The managed server doesn't go over your permissions, it rides on top of them. Treat the agent like a new coworker. Or better: like that fresh intern who does everything to the letter, no questions asked, and who's so afraid of getting it wrong that they don't even stop to think. The type who, if you tell them to go find the spark stockroom to store some in a bottle, will actually go looking. Yeah, the agent is just like that too: give it too much access and it'll use it, even when it makes no sense. So, least-privilege, scoped only to what the task needs, nothing beyond that. AWS added standardized IAM context keys for these managed MCP servers, so you can write policy that knows "this call came through the MCP server" and restrict accordingly.

Second: there's no long-lived key anywhere. With OAuth, what exists is a 1-hour token with automatic refresh; on the SigV4 path, temporary AWS CLI credentials that rotate on their own every 15 minutes. So no secret sits around in your shell history, your repo, or your .env, which is exactly where we tend to leak them.

Third: everything is auditable. CloudTrail logs every call and CloudWatch gives you the metrics. After an incident you can answer "what did the agent actually do?" with a straight face. If you can't answer that today about your current setup, that alone is reason enough to switch.

And one that's still coming: VPC endpoint support, for teams that need to keep this traffic inside the network boundary. If that's a hard requirement for you, wait for it before going to production.

My rule of thumb? One dedicated IAM role per agent purpose. If an agent gets compromised or goes sideways, the blast radius stops at that role. Don't reuse your admin identity. And don't hand it * on * "just to unblock the demo", because the demo becomes prod faster than you'd think.

Setting up the AWS account side (the essentials)

On the account side it's less than it seems, because the managed AWS MCP Server doesn't create IAM actions of its own. There's no mcp:Invoke to allow: it signs every call with SigV4 using your credentials and forwards it to the service, which authorizes against your usual policies. If your identity can't call logs:GetLogEvents, neither can the agent. Your current permissions are the boundary.

The quick-start is this: begin with a read-only identity (a dedicated role or an SSO permission set) and use the new context keys, aws:ViaAWSMCPService and aws:CalledViaAWSMCP, to deny destructive actions when the call comes from the agent, even if your role could do them. That way the agent reads all it wants and the dangerous verbs are blocked just for it. Then let CloudTrail show what it actually used and tighten the policy around that.

A simple guardrail, just so you get the idea:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "BlockDestructiveActionsViaMCP",
    "Effect": "Deny",
    "Action": ["dynamodb:DeleteTable", "s3:DeleteBucket", "lambda:DeleteFunction"],
    "Resource": "*",
    "Condition": { "Bool": { "aws:ViaAWSMCPService": "true" } }
  }]
}
Enter fullscreen mode Exit fullscreen mode

This setup deserves a post of its own, done as code. Later in the series I'll publish an "IAM for AI agents on AWS, with CDK" covering the full step by step (CLI, console and CDK), cdk-nag, org-wide SCP and multi-account. I'll link it here once it's out.

Which one to use: the decision changed

When this post first went out, the answer was "depends on the pain". Three weeks later, AWS settled it: the official setup guide now recommends migrating to the AWS MCP Server and removing Knowledge (and the older AWS API MCP) from your configuration. The reason is practical: duplicate tools confuse the agent and hurt performance, and it's the docs themselves telling you to clean up.

Knowledge wasn't shut down. It's still GA, credential-free, working. One legitimate case remains: you want ONLY doc lookups, with no AWS account and nothing to authorize (studying a service, say). For everything else, it's one server: the managed one, which already does credential-free doc search and operates the account when you authorize it. Less config, fewer conflicts, same IAM leash.

When NOT to reach for this

Because there's no silver bullet, and someone has to say it.

Don't drop this on a production account with no guardrails. Start in a sandbox and get your IAM boundaries right before the agent can touch anything that bills or deletes. In the Frugal Architect, Werner makes the point that cost is an architecture requirement, not something to find out at the end of the month, and with an agent firing off calls that goes double.

Don't grant broad permissions "for now". There's no "for now", trust me. Scope it from the first connection.

And don't leave anything irreversible on autopilot. Deletes, scaling actions, money movement: keep a human in the loop. The agent proposes, you approve.

Mind your region and compliance

A few things that matter if you operate outside us-east-1 (for me, that's sa-east-1, São Paulo).

Before pointing the agent anywhere, confirm the services and the managed server are available in your region. And here's the nice part: that's literally a question the MCP server itself answers for you (the doc search does it, no credentials). Check it instead of assuming.

On data residency and privacy laws (LGPD here in Brazil, GDPR and friends elsewhere), if the agent is going to touch resources with personal data, scope IAM so it can't read what it shouldn't, and use the CloudTrail trail as evidence of who accessed what. Auditability here isn't just good engineering, it's a compliance argument.

And for small teams: that "free" CloudTrail trail is gold when you don't have a dedicated security team. You get a record of everything the agent did without building anything.

To wrap up

  1. There are two AWS MCP servers for two pains: knowledge (stop hallucinating) and action (operate the account safely).
  2. The simple path is OAuth now: add the URL, log in through the browser, done. Works in Claude Code, the Claude app (Desktop and claude.ai), and Kiro.
  3. The managed one gets you off .env: a short-lived token (OAuth) or temporary CLI credentials (SigV4), with least-privilege and everything logged to CloudTrail.
  4. The official recommendation became one server: migrate to the AWS MCP Server and drop Knowledge from your config. It's still alive for credential-free doc lookups, but running both confuses the agent.

If you've been doing the .env hack, relax, everyone has. But the tools to stop are right here, they're managed, and they're auditable. There's no good excuse left to keep handing your account's keys to a robot that occasionally goes off the rails.

This post kicks off a series on MCP and agents on AWS. Next up I go deep on two tracks: setting up IAM as code (CDK) and OpenAI landing on Bedrock. Which one first? Tell me in the comments.

Liked it? Drop a like, tell me what you think in the comments, and share it with your crew to keep the community strong. Thanks a lot for reading this far. See you in the next one? =D

Want to go deeper

Prefer Portuguese? Read the PT version here.

Originally published on willpeixoto.dev.

Top comments (0)