Networking & Content Delivery
How Amazon CloudFront secures and accelerates the AWS MCP Server
The AWS MCP Server, a managed remote server for the Model Context Protocol (MCP), runs in production behind Amazon CloudFront. Hundreds of thousands of AWS accounts call it, and it handles millions of tool calls every month. Every request enters one of CloudFront’s more than 750 Points of Presence (PoPs), the edge locations nearest the caller. Two edge capabilities do the work there. AWS WAF inspects each request and blocks abusive traffic before it reaches the AWS MCP Server. Lambda@Edge, CloudFront’s edge compute, answers liveness checks, empty list requests and OAuth sign-in challenges in the PoP, without forwarding them to the origin (the AWS MCP Server in its Region). Together they protect the AWS MCP Server and optimize the load on it, so it scales as demand grows.
An earlier post, Protect MCP Endpoints at the Edge with Amazon CloudFront and AWS WAF, showed how AWS WAF secures an MCP endpoint. This post is the working example, running on the AWS MCP Server. We describe how CloudFront protects and optimizes the server, and why every request goes through it. We cover what happens to a request on arrival, which requests are answered at the edge, how the endpoint is protected from abuse, and what would break without any of it. You can apply the same capabilities to any public API or MCP server you build.
Introducing the AWS MCP Server
The AWS MCP Server gives any AI agent one managed endpoint to all of AWS. AWS runs it for every customer and serves agents worldwide. Customers add its single endpoint to their MCP client and reuse it for all their work on AWS. Through that one endpoint, an agent can look up AWS documentation and call AWS APIs under the customer’s own IAM credentials. AWS publishes dozens of open source MCP servers, and the AWS MCP Server brings them together behind that one endpoint. The setup guide recommends it in place of the AWS API MCP Server and the AWS Knowledge MCP Server, as a single managed endpoint simplifies setup and management operations.
The AWS MCP Server exposes around a dozen tools in two groups. The first group needs no credentials as it surfaces publicly available information to agents and users. These tools call search and read AWS documentation, list AWS Regions, and check regional availability. The second group runs against a caller’s own AWS account under IAM, so they require authentication and authorization. They can retrieve curated skills, run Python in a sandbox, retrieve tasks, and mint an Amazon S3 presigned URL for file uploads and downloads.
For authenticated access, customers connect in one of two ways. First, an MCP client that supports OAuth connects straight to the endpoint, with no local software. Second, a client that uses IAM credentials runs the open source MCP Proxy for AWS. The proxy signs each request with Signature Version 4 (SigV4).
What this workload demands of a front door
A public MCP endpoint needs what any public HTTPS API needs. It has to be secure, scale with demand, and respond fast. CloudFront terminates TLS near the caller and carries requests to the origin over the AWS backbone. Agent traffic adds two demands of its own. First, agents chain calls. An agent that searches the docs, reads a page and then checks a Region’s availability makes three calls in a row, and each call waits for the last one to finish. Second, a share of MCP calls are protocol overhead with fixed answers, like a ping or a request for an empty prompt list. We summarize the above into four key requirements below, with the last two being specific to MCP workloads. CloudFront meets all four in more than 750 PoPs.
1. It has to answer worldwide from multiple Regions
The AWS MCP Server runs in eight AWS Regions, and each Region has its own endpoint. The service is live in US East (N. Virginia), US West (Oregon), Europe (Frankfurt), Europe (Ireland), Europe (London), Asia Pacific (Singapore), Asia Pacific (Sydney) and Asia Pacific (Tokyo). Every capability is reachable through any of them. Wherever an agent runs, its request enters the nearest PoP and travels to the Region over the AWS backbone.
2. It has to be safe to expose to anyone at all
MCP traffic needs the same security as any HTTPS API. AWS WAF protects the endpoint for signed and unsigned callers alike. Credentials stay optional for the documentation tools, so anyone on the internet can call this endpoint. Every protection in this post has to work for a caller the service cannot identify.
3. It cannot afford to add a round trip to every call
A human user loads a web page, waits for one round trip, then reads. An agent works differently. It makes many calls one after another, and each call waits for the one before it to finish. Slow calls add up across the whole sequence, and the developer waits for that full total before the agent gives an answer. Cutting the time on each call is what keeps the agent fast. CloudFront cuts that time by ending TLS near the caller, reusing connections it already holds open to the origin, and answering routine calls in the PoP.
4. It has to answer routine protocol calls close to the caller
A share of MCP calls carry no real work. Clients send liveness checks and ask for lists the server leaves empty, like prompt templates. They repeat these calls every time they connect or reconnect. The origin gains nothing from serving them. Answering these calls without sending them to the origin reduces request load and volume on the origin.
Together, these four demands need global routing with compute at the edge. The front door answers POST calls that vary by caller, throttles each caller, and composes the response using the edge compute layer (Lambda@Edge). It answers or rejects close to the caller and sends the origin only real work. The rest of this post covers how CloudFront meets each demand.
The path every public request takes
The following diagram traces one request through CloudFront, from the agent to the Region. It is not a breakdown of the four demands. It shows each step in order, and where each one happens.
The steps are as follows.
- A request to the public endpoint resolves through Amazon Route 53, which points the service domain at the CloudFront distribution.
- The request enters the PoP nearest to the agent, and CloudFront terminates TLS there, so the handshake completes close to the client.
- AWS WAF evaluates the request first, and rejects blocked countries, blocked IP addresses on the AWS managed reputation list, and requests over a rate limit.
- The edge function reads the method named in the request body and uses it to choose how to handle the request. Reading the body is what makes the rest possible. The AWS MCP Server currently uses MCP version 2025-06-18, which names the operation in the body and nowhere in the URL or headers. The edge function also starts the OAuth flow. It serves the OAuth discovery document and returns the 401 challenge that prompts a client to sign in.
- The edge function answers static protocol methods and OAuth challenges in that PoP, without an origin request. Neither these nor the requests rejected at the edge reach the Region.
- Everything else is forwarded to the AWS MCP Server in the Region, which reports metrics to Amazon CloudWatch and audit records to AWS CloudTrail.
All of it is externally observable. Send a liveness check without credentials and read the headers.
$ curl -s -D- https://aws-mcp.us-east-1.api.aws/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"ping"}'
HTTP/2 200
content-type: application/json
server: CloudFront
x-cache: Miss from cloudfront
x-amz-cf-pop: DFW57-P8
{"jsonrpc":"2.0","id":1,"result":{}}
A documentation lookup sent without credentials and a fully signed call against a production account take the same route, so every caller meets the same perimeter in every one of those PoPs.
A rejected request looks different. AWS WAF returns an HTTP 403 when a request matches a blocked country, a flagged IP address, or a rule pattern. A caller over the rate limit gets an HTTP 429. Both come straight from the edge, carry no JSON-RPC body, and never reach the Region.
Step 2 applies to every request, whether or not it goes on to reach the Region. Beyond terminating TLS locally, CloudFront carries the request onward over connections it already holds open to the origin, so a request skips the cost of a new connection.
Answering requests at the edge
Look again at the response to that liveness check. It was composed at the edge and never reached a Region. The x-cache header reads Miss because no cache served the reply, and the edge function built it instead.
A small number of MCP methods are entirely static. A liveness check has one correct answer, and so does asking a server for prompt templates it does not publish. Neither depends on who is calling or on the state of anything behind the edge, so CloudFront answers them itself with an edge function attached to the distribution and the request never crosses a backbone link.
# static, answered at the edge
ping → {"jsonrpc":"2.0","id":1,"result":{}}
prompts/list → {"jsonrpc":"2.0","id":2,"result":{"prompts":[]}}
# real work, mints a session, so it traverses the full stack
initialize → {"protocolVersion":"2025-06-18",
"serverInfo":{"name":"AWSMCP","version":"1.0.0"}}
mcp-session-id: 373285ac-1053-4e2d-8d84-192265f6dcf8
Here CloudFront acts as compute, and no cache is involved. These replies cannot be cached anyway. A ping is a POST, and CloudFront does not cache POST responses. Each reply also carries the caller’s own request id, so a stored copy could not answer the next caller. The edge builds each reply fresh, and the origin never runs or pays for it. The edge function reads the body, recognizes the method, and returns a complete response from the location it is running in. Protocol overhead resolves at edge latency instead of Region latency, and a share of total request volume never becomes origin load, origin capacity or origin cost. These protocol calls arrive with every client that connects, so this is traffic the edge can plan for rather than chance.
As one example, measured from a single client against the AWS Edge location in Dallas, Texas, with twelve samples per method and the TLS handshake excluded, the two static methods returned in roughly 50 milliseconds. The two methods that continued to the Region took roughly 270 to 310 milliseconds. One client against one PoP is not a service-wide latency figure, and the absolute numbers move with the caller’s distance from the edge and from the Region.
The edge function handles the start of authorization as well. MCP clients expect OAuth 2.1, and the service accepts OAuth alongside IAM and SigV4. An OAuth client needs the server to publish discovery metadata and to answer an unauthorized request with a properly formed challenge. The edge function does both. It serves the OAuth discovery document and returns the 401 challenge from the PoP, so a client can find the authorization server and start sign-in without a Region round trip.
One distribution, four outcomes
It helps to see that alongside everything else that can happen to a request, because one distribution decides all of it.
The outcomes are as follows.
- AWS WAF or the edge function rejects the request. WAF acts first, before any function runs, and the edge function then applies its own per-account and per-IP limits.
- Static protocol calls like ping and prompts/list never leave the edge, and neither do OAuth challenges. The edge function (Lambda@Edge) reads the method from the request body, builds the reply in the PoP, and returns it to the caller.
- Documentation calls are forwarded to the Region and need no credentials to succeed.
- Calls that act on an AWS account are forwarded to the Region as well, where the caller is validated before any action is taken on their behalf.
Two of the four are settled without an origin request. The edge composes a fresh response where the request landed. That matters for your own service, because compute at the edge reaches request types like POST traffic and responses that vary by caller.
Securing the MCP endpoint
Credentials are optional on the documentation tools, so anyone on the internet can call the endpoint. The service still has to limit every caller, signed or not. CloudFront does this in the PoP, with AWS WAF and the edge function.
AWS WAF evaluates every request before any application code runs. It applies geographic match rules, AWS managed rule groups, and rate-based rule statements. The managed groups cover IP reputation and common issue patterns. Those rules inspect the request body. Limits follow the terms the protocol uses, not an undifferentiated request count. Opening a session, listing tools, and invoking a tool have different costs, so rules can be scoped to the method rather than the whole request.
The edge derives a limit for each caller from what the request carries, so signed and unsigned callers draw on separate allowances and an unsigned caller is still bounded. These edge limits protect the capacity of the service. The AWS MCP Server verifies each signed request before any tool runs, and it applies further limits once it knows who the caller is.
A caller that exceeds its allowance gets a clear answer rather than a silent failure, generated at the edge, from a request that never reached a backend. The response tells an unsigned caller that authenticating raises the limit, so the refusal carries its own remedy.
Two properties make those limits enforceable. First, CloudFront takes the client address from the connection itself, so a caller cannot choose it. Second, the origin cannot be reached except through the edge. CloudFront adds a secret header to every request it forwards, and the origin rejects anything that arrives without it. For details, refer to Restrict access to files on custom origins, which uses custom headers on origin requests.
A request the origin accepts therefore carries proof that it passed through CloudFront and met everything above on the way.
Observing traffic across every location
CloudFront and AWS WAF publish metrics and logs to Amazon CloudWatch. Operators can see in one place how much traffic arrived, how much was blocked and by which rule, how much the edge answered, and how much reached the origin.
The last two are the pair that changes how a service is read. Once the edge absorbs a meaningful share of traffic, the volume the origin sees is no longer a reliable proxy for the volume customers generate. Both have to be visible, and at the edge they are.
What CloudFront gives the AWS MCP Server
The earlier sections add up to four benefits for the service. Without CloudFront in front of the origin, the service would lose the first three outright, and the fourth would shrink to a view from the origin alone.
- Agents finish sooner. CloudFront terminates TLS near the caller, reuses open connections to the origin, and answers protocol overhead in the PoP. In the earlier measurement, static calls returned in about 50 milliseconds, against 270 to 310 milliseconds for calls that reached the Region. An agent saves that difference on each call the edge answers.
- The endpoint stays open and stays bounded. AWS WAF and the edge function turn away abusive and over-limit requests before they reach the Region, so one noisy caller cannot slow down the rest. The origin accepts traffic from CloudFront alone, so a caller cannot route around those limits.
- The origin handles only real work. Protocol overhead, OAuth challenges and rejected requests end at the edge. None of them uses origin capacity or adds origin cost.
- Operators see all of it in one place. CloudFront and AWS WAF metrics show what the edge absorbed next to what reached the origin, across every PoP.
What this means for your own service
The work the AWS MCP Server hands CloudFront is compute. The edge terminates connections, reads and routes requests, and enforces rules across more than 750 PoPs. Its edge function also builds the replies to static protocol calls and OAuth challenges, with no cache involved. A service can add CloudFront caching for shared responses on the same distribution as its needs. If you take one idea from this to your own service, take this one. CloudFront is edge compute, and caching is only one of the things it does. The AWS MCP Server uses it as compute and adds no cache today. For your own service, put each decision as close to the caller as you can, add caching where responses are shareable, and send the origin only the work that needs it.
None of these capabilities are specific to the AWS MCP Server. You can replicate or extend them for your own public MCP servers and other workloads. Agent traffic is new, and more services built to serve it will keep arriving. To get started, see Amazon CloudFront. For the service described here, see the Agent Toolkit for AWS user guide.

