Composability & the Agent Platform
All-in or à la carte; building a paved path for teams
- Explain the all-in pattern and which AgentCore service owns each production concern (hosting, persistence, tools, auth, monitoring, governance)
- Adopt AgentCore à la carte — keep your agent on EKS/Lambda/ECS and consume only Gateway, Code Interpreter, Browser, or Memory
- Design a tool-provider platform with Gateway + Registry that publishes governed MCP tools with centralized auth, observability, and compliance
- Connect agents with the A2A protocol using Agent Cards, and front a Runtime agent as a Gateway HTTP target (agent-as-tool)
- Choose a composition pattern based on team maturity and governance needs, and justify the trade-offs
AgentCore is not a monolith you adopt whole — its services compose. This lesson walks the three real architectures teams ship: the all-in scaffold (Runtime + Memory + Gateway + Identity + Observability + Policy), the à-la-carte cut (run your agent on EKS/Lambda/ECS and pull in only Gateway, Code Interpreter, Browser, or Memory), and the tool-provider 'paved path' (Gateway + Registry publishing governed MCP tools other teams consume). It then covers multi-agent composition: A2A between agents via Agent Cards, and fronting a deployed Runtime agent as a Gateway HTTP target so it becomes a tool other agents call.
- 1Modular by design: services that work together or alone
- 2Pattern 1 — All-in: the full scaffold
- 3Pattern 2 — À la carte: keep your agent, borrow a primitive
- 4Pattern 3 — Tool-provider: the paved path with Gateway + Registry
- 5Multi-agent composition: A2A and agent-as-tool
- 6Choosing a pattern by team maturity and governance
Modular by design: services that work together or alone
The single most important architectural fact about AgentCore is in the overview docs almost as an aside: the services are modular and "work together or independently." You do not have to adopt the whole platform. Each service has its own SDK/API surface and is independently billable, so you can wire up exactly the primitives your problem needs and run the rest of the stack however you already run it.
That modularity falls out of two foundational properties of the platform:
- Framework-agnostic — Runtime hosts a container that speaks a known protocol, not a framework. Strands, LangGraph, CrewAI, your own loop — they all live inside the container.
- Model-agnostic — the model is just a config value inside your agent code; AgentCore never inspects it.
Because of this, the docs frame AgentCore around three headline use cases, and these map directly onto the three composability patterns you'll build:
| Use case | What it is | Composability pattern |
|---|---|---|
| Agents | Autonomous apps that reason, use tools, keep context; serverless with isolated sessions, persistent memory, built-in observability | All-in scaffold |
| Tools / MCP servers | Turn existing APIs, databases, or services into MCP tools any agent can call via Gateway — without rewriting backends | Tool-provider platform |
| Agent platforms | Give internal teams a paved path with approved tools, shared memory, governed access, centralized observability/auth/compliance | Tool-provider + governance |
The rest of this lesson is those three patterns plus the multi-agent designs that connect them.
Key insight
"All or à la carte" is the real product
Most AgentCore tutorials teach the all-in scaffold first, which makes the platform look like an all-or-nothing commitment. It isn't. The dossier is explicit: you can use only Gateway (expose tools as MCP), only Code Interpreter (a managed sandbox), or only Memory (a managed store) while your agent runs on EKS/Lambda/ECS. Each service is a standalone managed primitive with its own client and its own bill.
Pattern 1 — All-in: the full scaffold
The all-in pattern is what you get when you scaffold a project with the CLI and let AgentCore own every production concern. The mental model: each service owns exactly one job.
| Concern | Service | What it does |
|---|---|---|
| Hosting | Runtime | Serverless container host; one Firecracker microVM per session, up to 8h, invoked via InvokeAgentRuntime |
| Persistence | Memory | Short-term events + long-term extracted records across sessions |
| Tools | Gateway | Turns APIs/Lambda/OpenAPI/MCP servers into MCP tools at one endpoint |
| AuthZ | Identity | Inbound auth + the token vault for outbound calls (no secrets in code or LLM context) |
| Monitoring | Observability | OTEL traces + CloudWatch metrics, per-session correlation |
| Governance | Policy | Cedar engine that intercepts every tool call before execution |
Status note (verify before relying on it): the first five services above (Runtime, Memory, Gateway, Identity, Observability) reached GA. AgentCore Policy's GA status is not first-party-confirmed as of writing — treat it as the dossier does (a service in flux) and check the live services page before you make it a hard dependency: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/what-is-bedrock-agentcore.html
The agent itself stays tiny — the SDK wrapper is famously "four lines to deploy":
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
app = BedrockAgentCoreApp()
agent = Agent() # framework + model live here
@app.entrypoint
def invoke(payload):
result = agent(payload.get("prompt", "Hello"))
return {"result": result.message}
if __name__ == "__main__":
app.run() # local http://localhost:8080; in container binds 0.0.0.0:8080Memory, Gateway, Identity, Observability, and Policy then attach around that entrypoint — you don't rewrite the agent, you compose services onto it. The CLI's develop → deploy → operate lifecycle is the all-in workflow:
# develop locally, then ship the whole scaffold
agentcore deploy # packages (CodeZip or Container/ECR), provisions a
# serverless Runtime endpoint with session isolation,
# CloudWatch logging, and observabilityIn operation you invoke the endpoint and attach Memory / Gateway / Identity / Browser / Code Interpreter as needed; monitor with Observability; govern with Policy.
Tip
Adopt all-in incrementally, not on day one
Even in the all-in pattern you don't have to turn everything on at once. Start with Runtime + Observability (you always want hosting and traces), add Memory when conversations need to persist across sessions, add Gateway when the agent needs governed tools, and add Identity/Policy when you have real users and real authorization requirements. The services are independent precisely so you can phase them in.
Pattern 2 — À la carte: keep your agent, borrow a primitive
Sometimes you already have an agent running happily on EKS, Lambda, or ECS, and you only have one hard problem — say, you need a sandbox to run model-generated code, or a managed browser, or a place to persist memory. The à-la-carte pattern says: leave your agent where it is and consume the single AgentCore service you need through its own client. Nothing forces that agent to run inside Runtime.
Only Code Interpreter — a managed, isolated sandbox for executing code. Your EKS-hosted agent calls it directly through the SDK:
from bedrock_agentcore.tools.code_interpreter_client import CodeInterpreter
code_client = CodeInterpreter("us-west-2") # region is positional
code_client.start() # spins up an isolated session
result = code_client.invoke("executeCode", {
"language": "python",
"code": "import pandas as pd; print(pd.__version__)"
})
code_client.stop()Only Memory — a managed store you read and write from anywhere. The control plane (bedrock-agentcore-control) creates the memory; the data plane (bedrock-agentcore) records and retrieves:
import boto3
data = boto3.client("bedrock-agentcore") # data plane
data.create_event(
memoryId="mem-123", actorId="customer-456", sessionId="session-789",
payload=[{"conversational": {"content": {"text": "..."}, "role": "USER"}}])
data.retrieve_memory_records(
memoryId="mem-123",
namespace="/customer-support/user-1/preferences/",
searchCriteria={"searchQuery": "...", "topK": 5})Only Gateway — expose your existing APIs/Lambda as MCP tools and point your own agent's MCP client at the gateway URL. (We build this out in Pattern 3.)
Only Browser — a managed, isolated cloud browser your agent drives with Playwright, browser-use, or Nova Act.
The through-line: every AgentCore service is a standalone managed primitive. À la carte is the lowest-commitment way onto the platform, and it's the right call when your agent stack is already mature and you have a single, specific operational gap to fill.
Watch out
À la carte means you own what you didn't outsource
If you run the agent yourself on EKS/Lambda and only borrow, say, Code Interpreter, then session isolation for the agent process, identity, and observability of the agent itself are still your problem — you only got the sandbox. The all-in scaffold gives you per-session microVM isolation and built-in identity/observability for free. À la carte trades that convenience for keeping your existing deployment. Choose deliberately.
Pattern 3 — Tool-provider: the paved path with Gateway + Registry
This is the pattern an organization reaches for when it wants to stop every team from re-inventing tool integrations and instead offer a paved path: a central place where approved, governed tools live, with auth, observability, and compliance handled once and shared.
Gateway solves the M×N integration problem (M agents × N tools). It converts APIs, Lambda functions, OpenAPI/Smithy schemas, and existing MCP servers into MCP-compatible tools behind a single endpoint, with both ingress and egress auth managed for you. A platform team creates a gateway once:
import boto3
client = boto3.client("bedrock-agentcore-control")
gw = client.create_gateway(
name="my-gateway",
roleArn="arn:aws:iam::123456789012:role/my-gateway-service-role",
protocolType="MCP", authorizerType="CUSTOM_JWT",
authorizerConfiguration={"customJWTAuthorizer": {
"discoveryUrl": "https://cognito-idp.us-west-2.amazonaws.com/<pool>/.well-known/openid-configuration",
"allowedClients": ["clientId"]}},
protocolConfiguration={"mcp": {"searchType": "SEMANTIC"}}) # enables semantic search
print(gw["gatewayUrl"]) # https://{gateway-Id}.gateway.bedrock-agentcore.{Region}.amazonaws.comTeams then add targets — e.g. a Lambda-backed tool, an OpenAPI service:
agentcore add gateway-target --name TestLambdaTarget --type lambda-function-arn \
--lambda-arn <ARN> --tool-schema-file tools.json --gateway TestGatewayConsuming agents (anywhere — Runtime, EKS, a laptop) point an MCP client at the gatewayUrl and call tools by their namespaced name: ${target_name}___${tool_name} — a triple-underscore prefix, e.g. LambdaUsingSDK___get_order_tool. With searchType="SEMANTIC", the gateway also exposes a built-in x_amz_bedrock_agentcore_search tool so agents can discover the right tool across thousands by intent rather than knowing its name.
Registry is the catalog half of the paved path. It's a centralized place to discover and manage agents, MCP servers, tools, skills, and custom resources across an org, with a governed publish/review/approve workflow and hybrid semantic + keyword search. Gateway exposes governed tools; Registry makes them discoverable and governable across teams. Together they are the dossier's literal definition of the tool-provider pattern: "Gateway + Registry to publish governed MCP tools other teams' agents consume."
Centralized governance is what makes this a platform rather than a shared URL:
- Centralized auth — Gateway is an MCP resource server. One authorizer (
CUSTOM_JWTvia Cognito/Okta/Auth0, or SigV4) gates inbound; outbound credentials are injected per-tool via Identity's token vault, so no team handles raw secrets. - Centralized compliance — attach a Cedar Policy engine to the gateway to intercept every tool call before execution (
policyEngineConfiguration={"mode":"ENFORCE"|"LOG","arn":"...policy-engine/..."}), plus per-invocation gateway interceptors (custom Lambda). - Centralized observability — every tool call flows through one endpoint, so the platform team gets one place to trace and monitor usage.
Watch out
Registry is preview — don't teach it as production-ready
As of writing, AgentCore Registry is listed as preview in the pricing/services tables (first 5k records free, then a per-record rate — all VOLATILE). The Gateway half of this pattern is GA; the catalog/governed-publish workflow via Registry is not yet GA. Confirm current status on the live AWS services page before committing a platform roadmap to it: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/what-is-bedrock-agentcore.html
Tip
Semantic search is a create-time-only decision
protocolConfiguration.mcp.searchType = "SEMANTIC" can only be set at gateway creation — you cannot enable it on an existing gateway; you'd have to recreate it. If you're building a paved path that will eventually host hundreds of tools, turn semantic search on from day one. The creator also needs bedrock-agentcore:SynchronizeGatewayTargets.
Multi-agent composition: A2A and agent-as-tool
Once you have more than one agent, the question becomes how they talk to each other. AgentCore gives you two distinct mechanisms, and they are not the same thing.
A2A — peer agents discover and call each other. A2A is one of the wire protocols a Runtime container can declare (alongside HTTP, MCP, AG-UI). It runs JSON-RPC 2.0 on port 9000 at the root path, and its defining feature is discovery via Agent Cards served at /.well-known/agent.json. An agent fetches another's Agent Card to learn what it can do, then calls it. The SDK ships a serve_a2a helper (install the bedrock-agentcore[a2a] extra):
from strands import Agent
from strands.a2a import StrandsA2AExecutor
from bedrock_agentcore.runtime import serve_a2a
agent = Agent(model="us.anthropic.claude-sonnet-4-20250514",
system_prompt="You are a helpful assistant.")
serve_a2a(StrandsA2AExecutor(agent), port=9000)
# serves /.well-known/agent.json (the Agent Card) + JSON-RPC + /pingAgent-as-tool — front a deployed agent as a Gateway HTTP target. The other mechanism turns a whole Runtime agent into a single tool that other agents call through Gateway. In Gateway's target taxonomy, AgentCore Runtime agents are an HTTP target — the one HTTP (proxied) target type. HTTP targets are path-based proxies: no aggregation, no semantic search, but they let a supervisor/orchestrator agent invoke a specialist agent exactly as if it were any other MCP tool.
The outbound-auth options differ from MCP targets, and Runtime HTTP targets uniquely support Caller IAM (via Forward Access Sessions) and token passthrough:
| Target | No auth | Gateway role | Caller IAM | OAuth 2LO | Passthrough |
|---|---|---|---|---|---|
| MCP server | Yes | Yes | No | Yes | No |
| AgentCore Runtime (HTTP) | No | Yes | Yes | Yes | Yes |
When to use which: reach for A2A when agents are peers that negotiate and delegate among themselves and you want capability discovery via Agent Cards. Reach for agent-as-tool when you have a clear orchestrator → specialist hierarchy and you want the specialist to appear in the same governed tool catalog as everything else, sharing the gateway's auth, policy, and observability.
Note
HTTP targets don't get aggregation or semantic search
Gateway has two modes: aggregation (MCP targets combined into one virtual MCP server with a unified tools/list) and direct/proxy (HTTP targets, path-based routing). Because a Runtime agent is an HTTP target, it is proxied, not aggregated — it won't show up in x_amz_bedrock_agentcore_search results and isn't part of the merged tool list. Plan discovery for agent-as-tool out of band.
Choosing a pattern by team maturity and governance
There is no single right architecture — the pattern follows your team's maturity and how much governance you need.
| Pattern | Best when… | Governance | Operational ownership |
|---|---|---|---|
| À la carte | You already run agents on EKS/Lambda/ECS and have one specific gap (sandbox, browser, memory) | You own auth/observability for the agent; AgentCore governs only the borrowed primitive | High — you keep your deployment |
| All-in | A new agent, or a team that wants the production scaffold handed to them | Built-in: per-session isolation, Identity, Observability, optional Policy | Low — AgentCore hosts and operates |
| Tool-provider / platform | A central team serving many downstream teams who should consume, not rebuild, tools | Highest: centralized auth, Cedar policy, one observability surface, governed catalog | Platform team owns the paved path; consumers just call it |
A useful progression for a growing organization:
- A team starts à la carte — they have a LangGraph agent on Lambda and just need a code sandbox. Lowest commitment.
- A new project goes all-in — they want isolation, memory, identity, and traces without building plumbing.
- As multiple teams accumulate overlapping tool integrations, a platform team stands up the tool-provider paved path so everyone consumes governed MCP tools from one Gateway (+ Registry, once GA), with auth and compliance handled centrally.
These patterns also compose with each other: an all-in agent in Runtime can consume tools from the platform team's Gateway, persist to a shared Memory store, and be fronted as a Gateway HTTP target so other teams' agents can call it. The composability isn't only within one architecture — it's across them.
Example
One agent, three patterns at once
A customer-support agent built all-in (Runtime + Memory + Observability) calls the platform team's Gateway for the Orders___get_order tool (tool-provider), while a separate fraud-detection agent still running on the team's own EKS cluster borrows only AgentCore Memory to share customer preferences (à la carte). The support agent is itself registered as a Gateway HTTP target so an orchestrator agent can delegate to it (agent-as-tool). All three patterns, one system.
Try it: Compose a paved path: front one agent as a tool for another
Goal: build a minimal tool-provider setup and prove the agent-as-tool composition end to end, then reason about which pattern fits.
Note on volatile facts: service status (Registry is preview as of writing), pricing, quotas, and region lists change — verify against the live AWS pages linked in Resources before you rely on any number.
- Deploy a specialist agent (all-in). Wrap a tiny Strands agent with
BedrockAgentCoreApp+@app.entrypoint(the four-line pattern) andagentcore deployit to Runtime. Confirm you can invoke it viaInvokeAgentRuntimewith aruntimeSessionId. - Create a gateway (tool-provider). Use
boto3.client('bedrock-agentcore-control').create_gateway(...)withprotocolType="MCP", aCUSTOM_JWTauthorizer (pointdiscoveryUrlat a Cognito user pool), andprotocolConfiguration={"mcp": {"searchType": "SEMANTIC"}}. Capture the returnedgatewayUrl. - Front the specialist as a Gateway HTTP target (agent-as-tool). Add the deployed Runtime agent as an HTTP target. Observe that it's proxied, not aggregated — confirm it does NOT appear in
x_amz_bedrock_agentcore_searchresults. - Add a real MCP/Lambda tool (M×N). Add a Lambda or OpenAPI target with
agentcore add gateway-target. Connect an MCP client togatewayUrland list tools — note the${target_name}___${tool_name}namespacing and the triple underscore. - Build an orchestrator that consumes both. Point a second agent's MCP client at the gateway and have it (a) call the namespaced Lambda tool and (b) delegate a sub-task to the specialist via the HTTP target. Strip the
${target_name}___prefix in your downstream dispatch. - (Stretch) Try A2A instead. Re-expose the specialist with
serve_a2a(StrandsA2AExecutor(agent), port=9000)and fetch its Agent Card from/.well-known/agent.json. Compare: when would you choose A2A (peers) over agent-as-tool (orchestrator → specialist via Gateway)? - Reflect (3–4 sentences). For your real system, which of the three patterns — à la carte, all-in, tool-provider — fits today, and what would push you to the next one? Tie your answer to team maturity and governance needs.
Key takeaways
- 1AgentCore services are modular — they "work together or independently," each with its own SDK/API surface and its own bill. The platform's three headline use cases (agents, tools/MCP servers, agent platforms) map onto three composability patterns.
- 2All-in: scaffold with the CLI so each service owns one concern — Runtime hosts, Memory persists, Gateway exposes tools, Identity authorizes, Observability monitors, Policy governs — while the agent itself stays a four-line entrypoint.
- 3À la carte: keep your agent on EKS/Lambda/ECS and consume only the primitive you need — only Code Interpreter, only Browser, only Memory, or only Gateway — via that service's standalone client. Lowest commitment, but you still own everything you didn't outsource.
- 4Tool-provider / paved path: Gateway converts APIs/Lambda/OpenAPI/MCP servers into governed MCP tools at one endpoint (solving M×N), and Registry (preview) catalogs them org-wide with a publish/review/approve workflow. Auth, Cedar policy, and observability are centralized so teams consume rather than rebuild.
- 5Multi-agent: A2A connects peer agents (JSON-RPC 2.0, port 9000, Agent Cards at /.well-known/agent.json via serve_a2a); agent-as-tool fronts a deployed Runtime agent as a Gateway HTTP target so a supervisor agent calls it like any tool.
- 6Gateway namespaces every tool as ${target_name}___${tool_name} (triple underscore); strip that prefix before dispatching downstream. Runtime HTTP targets are proxied (no aggregation/semantic search) but uniquely support Caller IAM and token passthrough.
- 7Choose by team maturity and governance: à la carte for mature stacks with one gap, all-in for new agents wanting the scaffold, tool-provider for a central team serving many. The patterns compose — one agent can use all three at once.
Quiz
Lock in what you learned
Check your understanding
0 / 4 answered
1.A team runs a LangGraph agent on EKS and only needs a secure place to execute model-generated Python. What's the most appropriate AgentCore composition?
2.In the tool-provider 'paved path' pattern, what is the specific role of AgentCore Registry as distinct from Gateway?
3.You want a supervisor agent to call a deployed specialist Runtime agent as if it were just another tool in your governed Gateway. How is the specialist wired in?
4.Which statement about the A2A protocol in AgentCore Runtime is correct?
Go deeper
Hand-picked sources to keep learning
The 'work together or independently' framing, the three use cases, and the live (growing) core-services table — your source of truth for which services are GA vs preview.
Aggregation vs proxy modes, MCP vs HTTP targets (including AgentCore Runtime agents as HTTP targets), and the M×N integration framing for the tool-provider pattern.
Why tools are named ${target_name}___${tool_name} and why you must strip the prefix before dispatching downstream.
Ports and discovery for each wire protocol — A2A on port 9000 with Agent Cards at /.well-known/agent.json.
Deep dive on Gateway as the enterprise tool-development layer — the paved-path narrative with examples.
Working code for à-la-carte clients, Gateway targets, and A2A/agent-as-tool composition you can adapt.