This repo deploys a minimal Amazon Bedrock AgentCore runtime whose main purpose is:
- preinstall
Claude Codeinside the runtime container - mount persistent AgentCore session storage at
/mnt/workspace - keep the only public entrypoint on AgentCore's IAM-authenticated runtime surface
- use Bedrock as Claude Code's backend
- expose the deployment through an SST v4 entrypoint (native SST/Pulumi — no agentcore CLI, no CDK)
The runtime app itself is intentionally small. The product signal here is the shell environment, not a rich HTTP agent.
sst.config.ts SST v4 app entrypoint; declares aws + aws-native providers; exports runtimeArn, runtimeId
infra/
image.ts ECR repository + Docker image build/push via @pulumi/docker-build
iam.ts Self-built least-privilege execution role (Sonnet 4.6 only)
runtime.ts aws-native BedrockAgentCore Runtime resource ("ClaudeShellRuntime")
app/claude_shell_poc/
Dockerfile Node 24 runtime image; native-installer Claude Code + shell tooling + Node ADOT
main.js Minimal AgentCore HTTP contract server (Node, CommonJS)
package.json Declares Node ADOT (@aws/aws-distro-opentelemetry-node-autoinstrumentation)
scripts/
exec.sh Opens an interactive AgentCore shell (reads ARN from .sst/outputs.json)
- The runtime execution role trusts only
bedrock-agentcore.amazonaws.com. - The PoC does not create any extra ALB, API Gateway, Lambda Function URL, or unauthenticated internet endpoint.
- Interactive shell access goes through
agentcore exec --it, which is IAM/SigV4 authenticated. - Claude Code's Bedrock permissions are defined in
infra/iam.tsand are genuinely least-privilege: the execution role's only Bedrock grant coversInvokeModel/InvokeModelWithResponseStreamscoped exclusively tofoundation-model/anthropic.claude-sonnet-4-6*and the cross-region inference profileus.anthropic.claude-sonnet-4-6. There is nofoundation-model/*wildcard. (The prior CDK-managed role attached a broad wildcard grant that could not be removed; the self-built role eliminates that entirely.)
- AWS credentials for account
<aws-account-id> - access to
us-east-1 - permission to deploy AgentCore runtimes and ECR repositories
- permission to open AgentCore shells against the deployed runtime
- Node.js 24+ and
npm - Docker (the image is built locally and pushed to ECR during deploy)
- First-time setup: run
npx sst installto download the Pulumi providers
cd /data/git/agentcore-claude-shell-poc
npm install
npx sst installnpx sst install downloads the aws and aws-native Pulumi providers declared in sst.config.ts. Run it once per machine (or after a provider-version bump).
cd /data/git/agentcore-claude-shell-poc
npm run deploynpm run deploy expands to sst deploy --stage dev. SST/Pulumi will:
- Build the Docker image from
app/claude_shell_poc/Dockerfileand push it to ECR (infra/image.ts). - Create or update the least-privilege execution role (
infra/iam.ts). - Create or update the AgentCore Runtime resource (
infra/runtime.ts).
On success, SST writes the deployed runtimeArn and runtimeId to .sst/outputs.json.
cd /data/git/agentcore-claude-shell-poc
npm run removenpm run remove expands to sst remove --stage dev. SST/Pulumi tears down the Runtime, IAM role, and ECR repository.
cd /data/git/agentcore-claude-shell-poc
npm run execnpm run exec runs ./scripts/exec.sh, which:
- Reads the runtime ARN from
.sst/outputs.json(keyruntimeArn). - Falls back to the
RUNTIME_ARNenvironment variable if the outputs file is absent. - Runs
npx @aws/agentcore@0.19.0 exec --it --runtime <arn> --region us-east-1.
You can also pass the ARN directly:
RUNTIME_ARN=<arn> ./scripts/exec.shInside the shell, the useful first checks are:
claude --version
env | grep -E 'CLAUDE|AWS_REGION|ANTHROPIC_MODEL'
aws sts get-caller-identity
ls -la /mnt/workspaceInside the runtime shell:
cd /mnt/workspace
git clone https://github.com/aws-samples/sample-mcp-server-s3.git
cd sample-mcp-server-s3
claude --bare --add-dir /mnt/workspacePrompt:
Read the README and src/. Tell me in 3 bullets:
1. what this MCP server exposes
2. what S3 operations it supports
3. what the local entrypoint is to run it
The human or role opening the shell needs runtime invoke permissions on the deployed runtime ARN. The ARN is written to .sst/outputs.json after npm run deploy. Example policy (replace <runtime-id> with the value from the deploy output):
{
"Effect": "Allow",
"Action": [
"bedrock-agentcore:InvokeAgentRuntime",
"bedrock-agentcore:InvokeAgentRuntimeCommand",
"bedrock-agentcore:InvokeAgentRuntimeCommandWithWebSocketStream"
],
"Resource": "arn:aws:bedrock-agentcore:us-east-1:<aws-account-id>:runtime/<runtime-id>"
}If you redeploy and the runtime ID changes, re-read .sst/outputs.json for the updated ARN. If your identity already has a broader AgentCore allow policy, you do not need to add another one for this PoC.