BuildInfrastructureAWS

AWS Bedrock AgentCore

agentfootprint's AgentCore adapter set — Memory, Identity, and Observability over the AgentCore data plane, tools over a Gateway's MCP endpoint, and Bedrock as the LLM. What's shipped, what you bridge yourself, and the one gotcha to know.

Amazon Bedrock AgentCore is AWS's managed runtime + primitives for agents (Memory, Identity, Gateway, Observability, Code Interpreter, Browser). agentfootprint is framework-side — it ships adapters for the data-plane primitives and consumes a Gateway over MCP. You bring the control plane (provisioning) and the runtime host; everything else is a port you fill with an AgentCore adapter.

Prefer hands-on?

Follow AgentCore: step by step — build mock-first, then swap to AgentCore one adapter (one line) at a time. This page is the reference map behind it.

Two AgentCore surfaces

Control plane (bedrock-agentcore-control) creates resources (CreateMemory, CreateGateway, CreateWorkloadIdentity, CreateAgentRuntime, …) — do this with the AWS SDK / CDK. Data plane (bedrock-agentcore) uses them at runtime — this is what agentfootprint's adapters wrap.

Capability → adapter map

CapabilityAgentCore API (plane → op)agentfootprintStatus
Memory — eventsdata → CreateEvent / GetEvent / ListEvents / DeleteEventAgentCoreStore (agentfootprint/memory-providers) + defineMemory({ store })✅ shipped
Memory — semantic retrievedata → RetrieveMemoryRecordsnot wrapped yet (agentcoreRetrieve() planned)🔴 bridge
Identity — workload tokendata → GetWorkloadAccessToken[ForUserId]agentCoreIdentity({ workloadName, userIdFor }) (agentfootprint/identity)✅ shipped
Identity — OAuth2 / API keydata → GetResourceOauth2Token / GetResourceApiKeyagentCoreIdentity()✅ shipped
Gateway — consume toolsGateway exposes an MCP endpointmcpClient(url).tools() (agentfootprint/tool-providers) → .toolProvider()✅ shipped
ObservabilityCloudWatch GenAI Observability + X-Ray (OTEL spans)agentcoreObservability() (agentfootprint/observability-providers)✅ shipped
LLMBedrock Conversebedrock() (agentfootprint/llm-providers)✅ shipped
Control plane (all Create*)control → Create*use AWS SDK / CDK🔴 bridge
Runtime harnessRuntime HTTP contract (/ping, /invocations)no TS harness — host the agent yourself🔴 bridge
Code Interpreter / Browserdata → Start*Sessionwrap as a defineTool or MCP tool🔴 bridge

Memory — AgentCoreStore

The store is just the Memory-store port pointed at an AgentCore Memory resource. Its methods map 1:1 to data-plane events; the agent code is identical to the in-memory version.

import { defineMemory, MEMORY_TYPES, MEMORY_STRATEGIES } from 'agentfootprint/memory';
import { AgentCoreStore } from 'agentfootprint/memory-providers';

const store = new AgentCoreStore({
  memoryId: process.env.AGENTCORE_MEMORY_ID!,
  region: 'us-west-2',
});

const memory = defineMemory({
  id: 'conversation',
  type: MEMORY_TYPES.EPISODIC,
  strategy: { kind: MEMORY_STRATEGIES.WINDOW, size: 10 },
  store,
});

Agent.create({ provider }).memory(memory).build();
  • put → CreateEvent, get → GetEvent, list → ListEvents, delete → DeleteEvent, forget → DeleteSession. The memory identity (conversationId) maps to the AgentCore sessionId.
  • The full memory deep-dive lives in Memory store adapters.
  • search() (server-side semantic retrieval over RetrieveMemoryRecords) isn't wrapped yet — use the WINDOW / TOP_K strategies until agentcoreRetrieve() lands.

Identity — agentCoreIdentity

import { agentCoreIdentity } from 'agentfootprint/identity';

const credentials = agentCoreIdentity({
  region: 'us-west-2',
  workloadName: 'workflow_assistant_agent',
  userIdFor: ({ principal }) => principal, // per-(workload, user) token vault
});

Agent.create({ provider, model, credentials }).build();

Resolves GetWorkloadAccessTokenForUserId / GetResourceOauth2Token at runtime. Swapping from dev static credentials to managed AgentCore identity is this one line — no tool-code change. Provisioning the providers (CreateWorkloadIdentity, CreateOauth2CredentialProvider) is control-plane → SDK / CDK.

Gateway — tools over MCP

An AgentCore Gateway turns a Lambda / OpenAPI / Smithy / MCP target into a single MCP endpoint with Identity-brokered egress auth. agentfootprint consumes it through the Tools/Gateway port:

import { mcpClient, staticTools, gatedTools } from 'agentfootprint/tool-providers';

const gateway = mcpClient(process.env.GATEWAY_MCP_URL!);
const tools = gatedTools(gateway, (name) => allowed.has(name)); // optional RBAC

Agent.create({ provider }).toolProvider(tools).build();

agentfootprint does not create Gateways (no control-plane client) — CreateGateway / CreateGatewayTarget are SDK / CDK.

Observability — agentcoreObservability

import { agentcoreObservability } from 'agentfootprint/observability-providers';
import { microtaskBatchDriver } from 'footprintjs/detach';

agent.enable.observability({
  strategy: agentcoreObservability({ region: 'us-west-2', logGroupName: '/agentfootprint/assistant' }),
  detach: { driver: microtaskBatchDriver, mode: 'forget' }, // keep the loop unblocked
});

Ships the typed AgentfootprintEvent stream to CloudWatch in AgentCore's GenAI-Observability schema. otelObservability() / cloudwatchObservability() / xrayObservability() are the other adapters behind the same port. Full step-by-step (AgentCore Observability and OTEL, multi-exporter, detach): Exporters: AgentCore & OTEL.

The one gotcha — streaming + tool calls

bedrock().stream() drops tool calls

In streaming mode, bedrock().stream() returns toolCalls: [] (it streams text but does not reconstruct tool_use from the deltas) — so a tool-using agent in streaming mode gets stopReason: "tool_use" with zero tool calls and finalizes empty. The provider's own fallback is to recover via complete(). Until reconstruction lands, route the streaming path through complete() for tool-using agents, or use complete() directly.

What you bridge yourself

agentfootprint is runtime-only, so these are yours (the AgentCore toolkit is Python; there is no JS harness):

  • Control plane — every Create* (Runtime, Memory, Gateway, WorkloadIdentity) via SDK / CDK.
  • Runtime host — the :8080 /ping + /invocations HTTP contract around agent.run() (e.g. a small Fastify/Express service or container).
  • RetrieveMemoryRecords, Code Interpreter, Browser — wrap as tools (defineTool or an MCP server) for now.

Next steps

On this page