The Model Context Protocol (MCP) has gone from a niche Anthropic spec to the default way agents call tools, and AWS now gives you three distinct ways to host one: AWS Lambda for stateless tools, ECS/Fargate for long-running servers, and Amazon Bedrock AgentCore for a fully managed, identity-aware runtime. This guide covers how to pick between them, how authentication actually works in 2026, and how to ship a working endpoint — with the trade-offs I've hit running these in real accounts.
If you're new to MCP itself: it's an open standard that lets a large language model discover and invoke external tools over a uniform JSON-RPC interface. A "server" is just the thing that exposes those tools. The interesting part on AWS isn't the protocol — it's where you run it and how you lock it down.
Which AWS deployment pattern should you use?
Pick by workload shape, not by what's newest. Lambda for stateless and bursty, Fargate for stateful and long-running, AgentCore when you want AWS to own the undifferentiated heavy lifting.
| Pattern | Best for | Auth | Scales to zero? | Operational load |
|---|---|---|---|---|
| Lambda + function URL | Stateless tools, bursty traffic | IAM (SigV4) or OAuth via adapter | Yes | Lowest |
| ECS / Fargate + ALB | Long-running, stateful, session-heavy | Cognito OAuth 2.0/2.1 | No | Medium |
| Bedrock AgentCore Runtime | Managed agent infra, framework-agnostic | Built-in identity + Cognito/OAuth | Yes | Low (managed) |
| AgentCore Gateway | Exposing existing Lambdas/APIs as MCP tools | Dual auth, SigV4 to targets | N/A | Low (managed) |
In practice, most teams I've worked with start on Lambda because the cost story is unbeatable — you pay per invocation and nothing while idle, which mirrors how agents actually call tools (in bursts, then silence for minutes). You graduate to Fargate or AgentCore only when you hit a real constraint: long-lived sessions, in-memory state, or the need for managed memory and identity.
When to skip building a server entirely
If your "tools" are already AWS Lambda functions or REST APIs, you may not need to write an MCP server at all. Amazon Bedrock AgentCore Gateway is a managed service that turns existing Lambda functions into MCP tools without you hosting or managing any infrastructure — each function becomes an MCP-compatible tool behind a single gateway URL, with built-in dual authentication. That's the fastest path from "I have some Lambdas" to "my agent can call them," and it's the option I reach for first on brownfield accounts.
Transport and protocol: what 2026 servers must ship
Use Streamable HTTP, full stop. The 2025-03-26 spec replaced the older HTTP+SSE transport with a single MCP endpoint — conventionally /mcp — that handles JSON-RPC over HTTP POST and optionally upgrades to Server-Sent Events for streaming responses. The 2025-06-18 revision then hardened authorization on top of it, and the current spec as of this writing is 2025-11-25.
The practical takeaway: every major client now negotiates MCP-Protocol-Version: 2025-06-18 (or later) by default, and SSE-only servers are dropping off the long tail. Don't build a new server on the deprecated HTTP+SSE transport — you'll be re-platforming it within the year.
On AWS, the runtime expectations are concrete:
- On AgentCore Runtime, the service expects your MCP server container to listen at
0.0.0.0:8000/mcp— the default path for most official MCP SDKs. - On Lambda, use a Lambda Web Adapter with response streaming enabled so your ASGI app can stream SSE chunks back to clients in near real time.
Authentication: IAM vs. OAuth 2.1
This is where most "it works locally but not in prod" pain lives. The rule the spec sets: HTTP-based servers should implement authorization; stdio servers should not — stdio servers retrieve credentials from the environment instead. So your auth choice follows your transport.
The IAM (SigV4) path — simplest on Lambda
If your MCP server is a Lambda function URL, the cleanest auth is AWS IAM. You grant lambda:InvokeFunctionUrl to the IAM principals allowed to reach the server, and clients sign requests with SigV4. AWS's reference implementations support exactly this: a custom Streamable HTTP transport over a Lambda function URL authenticated with IAM, or a custom transport that calls the Lambda Invoke API directly. No token server, no Cognito — IAM is the authorization layer.
This is my default for internal, machine-to-machine tools where every caller already lives in AWS. It's less moving parts than OAuth and the audit trail is just CloudTrail.
The OAuth 2.1 path — required for open remote servers
When your server is reachable by clients outside your AWS account, you're in OAuth 2.1 territory. The 2025-06-18 spec mandates:
- PKCE for all clients
- RFC 9728 protected-resource metadata, published at
/.well-known/oauth-protected-resource, advertising the resource URL and trusted authorization servers - RFC 8707 resource indicators, so tokens are bound to your specific MCP server and can't be replayed elsewhere
- Rejecting unauthenticated requests with HTTP 401 and a
WWW-Authenticateheader
On AWS, Amazon Cognito is the natural authorization server. AWS's own guidance for deploying MCP servers runs an OAuth flow through Cognito with the authorization-code grant: CloudFront (fronted by WAF) → ALB → an auth service on Fargate that redirects to Cognito, stores session and token state in DynamoDB with TTLs, then issues its own access token to the client. The MCP servers (on Fargate and Lambda) validate that token's signature against Cognito before processing a request.
You don't have to build all of that to start — but if you're exposing a server publicly, that's the production-grade shape, and it's worth deploying the auth stack with AWS CDK so it's reproducible.
Deploy a Lambda MCP server: the fast path
Here's the minimal shape for the most common starting point — a stateless tool on Lambda with IAM auth. AWS publishes a reference library for running MCP servers in Lambda; the deploy boils down to packaging your server, fronting it with a function URL, and locking the URL to IAM.
# 1. Package your MCP server (Python example) with the Lambda Web Adapter layer
# so the streamable-HTTP ASGI app runs unchanged in Lambda.
sam build
# 2. Deploy with a function URL authenticated by IAM (not public).
sam deploy \
--parameter-overrides AuthType=AWS_IAM \
--capabilities CAPABILITY_IAM
# handler.py — a tiny streamable-HTTP MCP server using the official SDK
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("aws-tools", stateless_http=True)
@mcp.tool()
def get_account_summary(account_id: str) -> dict:
"""Return a cost + resource summary for an AWS account."""
# ...call Cost Explorer / Resource Groups here...
return {"account_id": account_id, "monthly_spend_usd": 1234.56}
# The Lambda Web Adapter serves this ASGI app at /mcp with SSE streaming.
app = mcp.streamable_http_app()
Then grant a caller access:
aws lambda add-permission \
--function-name aws-tools-mcp \
--statement-id allow-agent \
--action lambda:InvokeFunctionUrl \
--principal arn:aws:iam::111122223333:role/agent-execution-role \
--function-url-auth-type AWS_IAM
That's a production-shaped server: scale-to-zero, per-request billing, IAM-audited, on the current transport. From here you swap AuthType=AWS_IAM for a Cognito-backed OAuth front end when you need to open it up. For the deeper IaC pattern — packaging, least-privilege roles, and CDK/SAM structure — our Terraform IaC on AWS guide and serverless CI/CD walkthrough cover the surrounding plumbing.
Going managed: MCP on Bedrock AgentCore
If you'd rather not own the runtime, memory, and identity yourself, deploy on Amazon Bedrock AgentCore Runtime. It runs your MCP server container in a serverless, framework-agnostic environment and provides the production substrate — runtime, memory, identity, gateway, observability — that agent frameworks don't give you on their own. AgentCore went generally available on October 13, 2025, so it's no longer a preview gamble.
Two patterns matter for MCP specifically:
- Host your server on AgentCore Runtime — package the container, listen on
0.0.0.0:8000/mcp, and let AgentCore handle scaling and identity. Good when the server is your own code. - Front existing tools with AgentCore Gateway — group multiple task-specific MCP servers (or raw Lambdas/APIs) behind one managed MCP interface. The gateway signs requests to backend targets with SigV4 using its service role, so you get a uniform, authenticated tool surface without re-writing anything.
I covered the full AgentCore service breakdown — the seven core services and how they fit together — in the Bedrock AgentCore guide. If you're studying for AWS's gen-AI cert, note that this maps directly onto exam content: the AIP-C01 exam tests implementing agentic AI solutions, and MCP plus AgentCore are squarely in scope.
A pragmatic decision rule
After shipping these a few different ways, here's the rule I actually use:
- Internal, stateless, bursty tool? → Lambda + function URL + IAM. Cheapest, simplest, done in an afternoon.
- Already have Lambdas/APIs you want agents to call? → AgentCore Gateway. Don't write a server.
- Public or multi-tenant server? → Fargate or AgentCore Runtime + Cognito OAuth 2.1. Eat the OAuth complexity; you need it.
- Stateful, long-lived sessions or managed memory? → AgentCore Runtime. Stop fighting Lambda's execution model.
The mistake I see most often is reaching for ECS/Fargate by default because it "feels production." For an MCP tool that's called in bursts, a 24/7 container is just a bill — Lambda's scale-to-zero is the better-architected choice until you have a concrete reason to leave it.
Build it hands-on
Reading the spec only gets you so far — MCP deployment clicks once you've wired IAM auth, watched a SigV4 request get signed, and debugged a 401 with a missing WWW-Authenticate header yourself. Practice on CloudaQube's hands-on AWS labs to deploy real serverless and agent infrastructure in a live account, then take what you've built straight into the AWS Generative AI Developer – Professional cert path, where MCP and AgentCore show up directly on the exam.
Sources: AWS — Deploying MCP servers on AWS (Guidance), Amazon Bedrock AgentCore — Deploy MCP servers in Runtime, awslabs — Run MCP servers with AWS Lambda, and the Model Context Protocol authorization specification.