Amazon Bedrock AgentCore for Beginners: The Complete Series
Nine parts, each one deploying something real. Start with an agent that can add two numbers, end with one that drives a browser — and find out where the hard parts actually are.
Amazon Bedrock AgentCore is a set of building blocks for running AI agents on AWS: somewhere to run them, a way to give them tools, a way to authenticate, somewhere to keep what they remember, and a way to see what they did.
That is a lot of surface area, and most of the documentation explains one piece at a time. This series builds all of it in order, one working project per part. Every part deploys something real with Terraform, and every part ends with what it actually taught — including the things that cost an afternoon to discover.

You can read them in order, which is how they were written, or take the one you need. Each project stands on its own.
Foundations
Part 1 — Build Your First AI Agent
An agent with four tools — add, subtract, multiply, divide — containerised and deployed to AgentCore Runtime with Terraform.
The four tools exist because a language model predicting the next token is not a calculator. That single fact turns out to be the thread running through the whole series. This part also settles the question everyone asks first: AgentCore Runtime is infrastructure, a box your container runs inside, in the same sense that Lambda is. It answers "why not just use Fargate?" too.
Part 2 — Build an MCP Server on AgentCore Runtime
The same tools, moved out of the agent into a standalone MCP server — hosted on Runtime, called over the wire. No model and no agent framework anywhere in it.
MCP is an agreement, not a product: two questions, tools/list and tools/call, over JSON-RPC. Discovery is the reason to prefer it over REST when the caller is a model — add a tool and clients see it; nobody edits an integration. Switching Runtime from HTTP to MCP is one Terraform word and a different port.
Connecting to tools
Part 3 — Connect an Agent to Tools with AgentCore Gateway
A Gateway in front of your tools, turning a Lambda into MCP tools an agent can discover.
The agent ends up holding one URL and one credential, not one per backend. The tool catalogue is discovered rather than configured — nothing in the agent names a tool. Adding a second backend is a new Terraform resource, not a code change.
Part 4 — Secure the Gateway with OAuth 2.0 and JWT
Inbound authorization: who is allowed to call your Gateway, using CUSTOM_JWT, Amazon Cognito and an OIDC discovery document.
Client credentials is the right grant here because you are authenticating a workload, not a person. The Gateway needs exactly one URL to establish trust, plus an allow-list.
Part 5 — Call OAuth-Protected APIs with AgentCore Identity
Outbound authorization: how your Gateway authenticates to someone else's protected API.
Inbound and outbound are separate settings, and conflating them is the most common way to get stuck. AgentCore Identity holds the OAuth client and the Gateway asks it for a token at invocation time, so the agent's code contains no OAuth at all. One trap worth reading before you build: the target type decides which outbound auth you can use.
State and insight
Part 6 — Give Your Agent Memory Across Conversations
An agent that remembers a preference from one conversation and uses it in a completely separate one.
Short-term and long-term memory are different things: events are the conversation, long-term memory is what a strategy derived from it. Without a strategy you have event storage and nothing else. And replaying yesterday's transcript into today's prompt is not memory — it works, it is sometimes right, and it grows without limit.
Part 7 — Find the Slow Tool with AgentCore Observability
An agent that takes six seconds, and logs that cheerfully agree it took six seconds without telling you where they went.
Logs say what happened; only a trace says which part. This part instruments the agent with OpenTelemetry and reads the waterfall back out of CloudWatch. The result is not what you would guess: the deliberately slow tool was real, and still not the biggest cost — the model's round trips were. There are five switches that have to be on, four of them fail silently, and the fifth cannot be expressed in Terraform at all.
The built-in tools
Part 8 — Run Model-Written Code Safely with Code Interpreter
Part 1 gave the model four arithmetic tools. That does not scale — you cannot write a tool for every question someone might ask. So give it one tool that runs code, and let it write the code.
The obvious implementation of that tool is exec(), and it is the wrong one: model-written code would run with your credentials and your filesystem. aws.codeinterpreter.v1 already exists in every account, so the entire Terraform for this part is an IAM policy. The honest part of this post is what the sandbox doesn't fix — it guarantees the code you wrote is the code that ran, not that the code was right.
Part 9 — Let Your Agent Browse the Web with AgentCore Browser
A real Chrome running in AWS, driven from your laptop with Playwright over the DevTools Protocol.
It opens with a measurement rather than an argument: the same page fetched by HTTP returns 5806 bytes, HTTP 200, and zero of the content, because the page renders in JavaScript. Nothing errors — which is exactly why an agent will then reason confidently about a page it never saw. This part also has the most useful failures in the series, because the browser worked perfectly every time and the agent still got the answer wrong three times running.
What the whole thing taught
Nine parts in, one pattern stands out, and it is not the one I expected when I started.
The infrastructure is the part you can make reliable. Every AWS service in this series did what it said it would. Every wrong answer came from the reasoning layered on top — a model that read three pages correctly and then added 3 + 1 + 2 to get 5, or wrote = where it needed += and reported a confident, wrong number.
The fixes were almost never a bigger model or a better service. They were a tool that does the thing the model cannot, an error message written for a model to read, and a way for it to check its own work.
Build the boring, checkable scaffolding. That is the job.