npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aws/agentcore-cdk

v1.0.2

Published

L3 CDK constructs for Amazon Bedrock AgentCore

Readme

@aws/agentcore-cdk

L3 CDK constructs for Amazon Bedrock AgentCore. Deploy agent infrastructure with strongly-typed, declarative specifications.

Installation

npm install @aws/agentcore-cdk

Note: aws-cdk-lib and constructs are peer dependencies. If you don't already have them:

npm install @aws/agentcore-cdk aws-cdk-lib constructs

Quick Start

An AgentCore project is a directory with an agentcore/agentcore.json (written by agentcore project create). The CDK app the AgentCore CLI vends into agentcore/cdk/ is the smallest complete use of this library — three calls in bin/cdk.ts and one construct in lib/cdk-stack.ts:

// bin/cdk.ts
#!/usr/bin/env node
import { App } from 'aws-cdk-lib';
import { readAgentCoreProject, resolveTargetStacks, transformAgentCoreJson } from '@aws/agentcore-cdk';
import { AgentCoreStack } from '../lib/cdk-stack';

try {
  // The AgentCore CLI runs this app from agentcore/cdk/; readAgentCoreProject walks up to agentcore/.
  const project = readAgentCoreProject();
  const app = new App();
  for (const stack of resolveTargetStacks({
    projectName: project.projectName,
    targets: project.targets,
    deployedState: project.deployedState,
  })) {
    new AgentCoreStack(app, stack.stackName, {
      env: stack.env,
      tags: stack.tags,
      description: stack.description,
      application: transformAgentCoreJson(project.agentCoreJson, {
        projectRoot: project.projectRoot,
        credentials: stack.credentials,
        target: stack.target,
      }),
    });
  }
  app.synth();
} catch (error) {
  console.error('AgentCore CDK synthesis failed:', error instanceof Error ? error.message : error);
  process.exit(1);
}
// lib/cdk-stack.ts
import { AgentCoreApplication, type AgentCoreApplicationProps } from '@aws/agentcore-cdk';
import { Stack, type StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export interface AgentCoreStackProps extends StackProps {
  /** Props for the AgentCore application, produced by transformAgentCoreJson from agentcore/agentcore.json. */
  application: AgentCoreApplicationProps;
}

/**
 * The stack the AgentCore CLI deploys. Everything declared in agentcore/agentcore.json is
 * created by the AgentCoreApplication construct. Add your own resources below it and wire
 * them to your runtimes and harnesses through the application's accessors.
 */
export class AgentCoreStack extends Stack {
  public readonly application: AgentCoreApplication;

  constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
    super(scope, id, props);
    this.application = new AgentCoreApplication(this, 'Application', props.application);

    // Example: give a runtime a DynamoDB table.
    //
    // import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
    // const orders = new dynamodb.Table(this, 'Orders', {
    //   partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
    // });
    // const checkout = this.application.runtime('checkout'); // or .harness('support')
    // checkout.grantReadWrite(orders);
    // checkout.addEnvironmentVariable('ORDERS_TABLE', orders.tableName);
  }
}

The three entry points:

| Function | What it does | | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | readAgentCoreProject(startDir = process.cwd()) | Walks up to the nearest agentcore/agentcore.json and reads the project files once: the parsed agentcore.json, the validated project name, aws-targets.json ([] when absent) and agentcore/.cli/deployed-state.json (undefined when absent, a malformed file throws). The only place the app touches the working directory. | | resolveTargetStacks({ projectName, targets, deployedState }) | One TargetStack per deployment target, AgentCore-<project>-<target>, pinned to the target's account/region, tagged agentcore:project-name and agentcore:target-name, with that target's credential providers, or one environment-agnostic AgentCore-<project> stack (project tag only) when there are no targets yet. | | transformAgentCoreJson(agentCoreJson, { projectRoot, credentials, target }) | Validates agentcore.json, reads each harness's harness.yaml and system-prompt.md and every non-S3 knowledge-base connector file under projectRoot, and returns the AgentCoreApplicationProps for one AgentCoreApplication. target is the stack's deployment target, whose name becomes AgentCoreApplicationProps.targetName. Synchronous, deterministic, no network, no process.env. |

Every relative path in the spec resolves against projectRoot, so synthesis never depends on the working directory.

Every physical AWS resource name is <project><sep><target><sep><name>: the project name, the deployment target name and the resource's spec name, joined by the separator the service accepts (_ for AgentCore resources other than gateways and for knowledge bases, - for gateways and Lambda functions, / for ECR repositories, which are also lowercased). Project names are letters and digits and target names are letters, digits and hyphens. With the _ separator each - in the target becomes _, because those services only allow letters, digits and underscores, so runtime checkout deployed to target prod-us is Shop_prod_us_checkout; the - and / separators keep the target as is. The target reaches the constructs through transformAgentCoreJson's target option, which sets AgentCoreApplicationProps.targetName, and the vended bin/cdk.ts passes target: stack.target, so runtime checkout of project Shop deployed to target prodEu is Shop_prodEu_checkout. Without a target (the project build stack, or AgentCoreApplication used without targetName) the name is <project><sep><name>. A composed name longer than the service's limit fails at synth, naming the resource, its length and the limit.

Constructs

AgentCoreApplication

Main L3 construct for deploying agent environments. It takes the project spec (agentcore.json), the harness configurations, the deployed credentials, an optional targetName (the deployment target, the middle segment of every physical resource name) and a required projectRoot (the directory that contains agentcore/; every relative path in the spec resolves against it, so synthesis never depends on the working directory).

The application creates everything agentcore.json declares, so one construct owns the whole spec. Gateways (Gateway<name>), the compute behind their targets (LambdaToolTarget<name>, RuntimeToolTarget<name>) and standalone tool runtimes (ToolRuntime<name>) are direct children of the application. Payment managers and connectors are created under the Payments child at stack scope, with the construct ids the AgentCore CLI's original template used (Payment<manager> and Payment<manager><connector>, underscores removed), so a stack that template deployed keeps its resources. Those ids must not change.

Once every resource exists the application binds each one to the workloads that use it (see Binding AgentCore resources): every memory and gateway to every runtime, payment managers to Python HTTP runtimes, each harness's referenced memory and every gateway to that harness, and each connections[] entry and tool runtime binding to the workload that names it.

RuntimeEnvironment

One entry of runtimes[]: the AgentCoreRuntime, its build resources, its endpoints and its outputs.

Extending the application

Get resources

Use a getter when the resource must exist. A typo or missing resource fails at synth and lists the available names:

const checkout = this.application.runtime('checkout');
const support = this.application.harness('support');
const tools = this.application.gateway('tools');
const history = this.application.memory('history');

Other getters are knowledgeBase(name), evaluator(name), onlineEvalConfig(name), policyEngine(name), configBundle(name), capacityProvider(name), toolRuntime(name), paymentManager(name) and paymentConnector(manager, connector). Use the corresponding typed map, such as memories.get(name), when a resource is optional or when iterating. runtimeEnvironments, harnessRoles and toolLambdaFunctions are map-only. A legacy role-only harness is available through harnessRoles; harness(name) returns only a fully synthesized harness.

Grant permissions

The constructs that own an execution role (AgentCoreRuntime, AgentCoreHarness, AgentCoreHarnessRole and AgentCoreGateway) implement iam.IGrantable, so any AWS L2 grant accepts them. Runtimes and harnesses also expose grantRead / grantWrite / grantReadWrite for DynamoDB tables, S3 buckets and Secrets Manager secrets (each delegates to the resource's own grant method, so the IAM actions stay owned by aws-cdk-lib), grant(actions, resources), addToPolicy / addToRolePolicy, and addEnvironmentVariable:

import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';

const orders = new dynamodb.Table(this, 'Orders', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});
const checkout = this.application.runtime('checkout');
checkout.grantReadWrite(orders); // updates the runtime's execution role
checkout.addEnvironmentVariable('ORDERS_TABLE', orders.tableName);
orders.grantReadData(this.application.harness('support')); // any AWS L2 grant works too

const reports = new s3.Bucket(this, 'Reports');
checkout.grantWrite(reports, 'checkout/*'); // s3:PutObject + s3:DeleteObject* on checkout/* only

const apiKey = new secretsmanager.Secret(this, 'PartnerApiKey');
checkout.grantRead(apiKey); // secrets are read-only for a workload; grantWrite(secret) throws
checkout.addEnvironmentVariable('PARTNER_API_KEY_ARN', apiKey.secretArn);

AgentCore resources also provide grants for their own data-plane operations: runtimes have grantInvoke, grantExec and grantInvokeAll; harnesses and gateways have grantInvoke; memories have grant and grantWithAccess; payment managers have grantProcessPayment. Use these when the caller already knows how to find the resource:

const support = this.application.harness('support');

this.application.runtime('search').grantInvoke(support);
this.application.memory('history').grantWithAccess(support, 'read');
this.application.gateway('tools').grantInvoke(support);
this.application.paymentManager('billing').grantProcessPayment(support);

Imported roles. A runtime, harness or gateway configured with an executionRoleArn uses a role CDK cannot modify. Every grant path — the conveniences, grant, addToPolicy, and any L2 grant made through grantPrincipal — emits a synth-time warning listing the actions that were not attached; the imported role must already carry them.

Environment variable limits. Both resources accept at most 50 variables; keys must match ^[a-zA-Z_][a-zA-Z0-9_]*$ and be 1–100 characters; values may be at most 2048 characters. addEnvironmentVariable validates at call time and names the construct, the key and the limit; setting a key to the value it already has is a no-op, setting it to a different value is an error.

Binding AgentCore resources

AgentCoreMemory, AgentCoreGateway, AgentCorePaymentManager and AgentCoreRuntime implement IBindable. bind(workload) grants the workload's execution role the resource's data-plane access through the resource's own grant method and sets the variables the workload's code reads to find it, all under the resource's discoveryPrefix: MEMORY_<NAME> for a memory, AGENTCORE_<TYPE>_<NAME> for a gateway, payment manager or runtime, and <TYPE>_<ID> for a resource imported by ARN, with the name uppercased and every other character replaced by _. The memory and imported names, and the credential names in the table below, match what the v0 CLI deployed. Runtimes and harnesses are the workloads (IAgentCoreWorkload). Use grant* when only IAM permission is needed; use bind when the workload also needs discovery environment variables.

The application binds the relationships declared in agentcore.json. A stack extending the application can bind additional relationships or resources imported by ARN:

import { AgentCoreMemory } from '@aws/agentcore-cdk';

const checkout = this.application.runtime('checkout');
const shared = AgentCoreMemory.fromMemoryArn(
  this,
  'shared',
  'arn:aws:bedrock-agentcore:us-west-2:123456789012:memory/x'
);
shared.bind(checkout, { access: 'read' }); // MEMORY_SHARED_ID and _ARN, read actions on the ARN

const support = this.application.harness('support');
this.application.toolRuntime('search').bind(support, { envVarName: 'SEARCH_TOOL_ARN', exec: true });
this.application.paymentManager('billing').bind(support);

| Resource | Prefix | Variables | | --------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | Memory | MEMORY_<spec name>, or MEMORY_<import id> | ID, ARN | | Gateway | AGENTCORE_GATEWAY_<spec name>, or GATEWAY_<import id> | URL, ARN, AUTH_TYPE (AWS_IAM, CUSTOM_JWT, NONE), CREDENTIAL_PROVIDER for CUSTOM_JWT | | Payment manager | AGENTCORE_PAYMENT_<spec name> | MANAGER_ARN, PROCESS_PAYMENT_ROLE_ARN, CONNECTOR_ID (first connector), AUTO_PAYMENT, TOOL_ALLOWLIST, NETWORK_PREFERENCES, AUTH_MODE | | Runtime (as a tool) | AGENTCORE_RUNTIME_<runtime name>, or RUNTIME_<import id> | ARN, or the binding's envVarName verbatim | | Browser, code interpreter (connections) | BROWSER_<connection id>, CODE_INTERPRETER_<connection id> | ID when an ARN is given, nothing for the AWS default | | Credential | CREDENTIAL_<credential name>, . and - replaced by _ | NAME, the provisioned provider name (from the recorded ARN) |

For a project Gateway with protocolType: "MCP", URL is the complete MCP endpoint returned by the service. For protocolType: "None", URL is the bare Gateway origin: append /mcp to use its MCP interface, or append the route for the HTTP target being called. Imported Gateways remain MCP-oriented because an ARN does not carry protocol metadata, so their derived URL ends in /mcp.

The import id of a connections[] entry is connectionTokenFor(connection): the connection id, or <type>-<resource id> when there is none, uppercased with every other character replaced by _, the same token the AgentCore CLI bakes into generated code. Binding the same resource to a workload twice is a no-op. Two resources that share a prefix and set a variable to different values fail at synth naming the workload and the variable.

Container builds in a VPC

When a Container-build agent (or harness) sets networkMode: VPC, the build infrastructure — the orchestrator Lambda and the shared CodeBuild project — is placed in the same VPC as the runtime, using networkConfig.subnets and networkConfig.securityGroups. CodeBuild additionally requires networkConfig.vpcId (its API cannot infer the VPC from subnets); it is required only for Container builds in VPC mode.

All Container agents and harnesses in a single project must build in the same VPC — the CodeBuild project is shared per stack and synthesis fails fast on a mismatch. Container builds in VPC mode allow at most 5 security groups (a CodeBuild limit), vs 16 for the runtime.

Network prerequisites. Private subnets must be able to reach the services the build uses, or the build will hang until timeout:

  • The build Lambda calls CodeBuild (StartBuild/BatchGetBuilds) and must reach the CloudFormation response endpoint (S3).
  • CodeBuild must reach ECR (api + dkr), S3 (source asset), CloudWatch Logs, STS, and any registry the Dockerfile pulls base images from.

Provide a NAT gateway or VPC endpoints for: ECR (api, dkr), S3 (gateway), CloudWatch Logs, CodeBuild, and STS — plus egress for public base-image pulls.

IAM authentication for Gateway targets

MCP server and OpenAPI targets can authenticate with the Gateway's execution role by setting outboundAuth.type to GATEWAY_IAM_ROLE. Set service to the target's SigV4 service name, such as bedrock-agentcore for an AgentCore Runtime or execute-api for an API Gateway endpoint. region is optional; when omitted, signing uses the Gateway's region. No named OAuth or API key credential is needed.

{
  "name": "runtime-tools",
  "targetType": "mcpServer",
  "endpoint": "<IAM-protected MCP endpoint URL>",
  "outboundAuth": {
    "type": "GATEWAY_IAM_ROLE",
    "service": "bedrock-agentcore",
    "region": "us-west-2"
  }
}

OpenAPI targets use the same outboundAuth configuration alongside their schemaSource. For an external target, grant the required target-service permissions to the Gateway's execution role. For example, an AgentCore Runtime requires bedrock-agentcore:InvokeAgentRuntime; an API Gateway endpoint requires execute-api:Invoke. The service and region fields are valid only with GATEWAY_IAM_ROLE.

Standalone Usage

These constructs can be used independently without the CLI. Build the props from a project directory:

import { AgentCoreApplication, readAgentCoreProject, transformAgentCoreJson } from '@aws/agentcore-cdk';

const project = readAgentCoreProject('/path/to/my-project');
new AgentCoreApplication(
  this,
  'App',
  transformAgentCoreJson(project.agentCoreJson, { projectRoot: project.projectRoot })
);

or pass a spec directly with the required project root that the spec's relative paths resolve against:

import { AgentCoreApplication } from '@aws/agentcore-cdk';

new AgentCoreApplication(this, 'App', {
  spec: {
    name: 'myProject',
    version: 2,
    runtimes: [
      {
        name: 'myAgent',
        build: 'CodeZip',
        entrypoint: 'main.py',
        codeLocation: 'app/myAgent/',
        runtimeVersion: 'PYTHON_3_12',
      },
    ],
  },
  projectRoot: '/path/to/my-project',
});

Related Package

  • @aws/agentcore - CLI tool that uses these constructs via templated CDK projects

Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.