Claude Code Skills invocando o Bedrock AgentCore Code Interpreter
Por Fabio Douek
Visão Geral
Eu queria uma ferramenta de troubleshooting que permitisse ao Claude Code consultar logs da AWS sem dar acesso direto às minhas contas AWS, e também fornecer least privilege. O caso de uso: investigar eventos do CloudTrail armazenados no CloudWatch Logs Insights a partir de uma conta de auditoria que registra atividades em toda a organização AWS. O código roda em outro lugar, em um ambiente restrito com sua própria IAM role e sem possibilidade de comunicação externa.
O Amazon Bedrock AgentCore Code Interpreter oferece exatamente isso. Ele cria microVMs Firecracker com runtimes de Python, JavaScript e TypeScript, gerencia o ciclo de vida das sessões e faz streaming dos resultados de volta. As sessões recebem 2 vCPU, 8 GB de RAM e 10 GB de disco. Você paga por segundo de uso real de CPU, e o tempo de espera de I/O é gratuito.
Embora o cenário acima seja simples e de risco relativamente baixo para o propósito deste post, a mesma abordagem pode ser usada para cenários onde permissões de escrita estão envolvidas, para modificar recursos na AWS, e permissões cross-account podem ser concedidas para permitir que você alcance todas as contas AWS em uma AWS Organization.
O plano: construir um binário Go que encapsula a API do AgentCore Code Interpreter, empacotá-lo como um plugin do Claude Code com um skill que sabe como usá-lo, e publicá-lo em um plugin marketplace. O binário Go gerencia o ciclo de vida das sessões, execução de código e streaming de saída. O skill diz ao Claude quando e como invocá-lo. O resultado é um comando /code-interpreter-execute que permite ao Claude executar código em um sandbox seguro com uma única invocação.
Arquitetura
O fluxo:
- Claude Code recebe uma solicitação do usuário (ex:
/code-interpreter-execute query CloudTrail for role creation events). - O Skill (
/code-interpreter-execute) diz ao Claude como usar a ferramenta e restringe-o a invocar apenas o binário do sandbox. - O binário Go (
agentcore-sandbox) gerencia o ciclo de vida da sessão (start, execute, stop) e faz streaming dos resultados de volta para o Claude via API do AgentCore. - O AgentCore Code Interpreter cria uma microVM Firecracker, executa o código Python usando sua IAM execution role com escopo definido.
- A execution role permite que o sandbox chame as APIs do CloudWatch Logs para consultar eventos do CloudTrail, e nada mais.
O skill e o binário Go são ambos empacotados dentro do plugin. O Claude Code adiciona o diretório bin/ do plugin ao PATH automaticamente, então o skill pode invocar o binário como um comando direto.
Setup
Pré-requisitos
- Claude Code 2.1.91+: o suporte a plugin marketplace requer esta versão ou posterior. Verifique com
claude --versione atualize comclaude updatese necessário. Para mais detalhes sobre como plugins do Claude Code distribuem binários específicos por plataforma, veja Claude Code Plugin Binaries. - CloudTrail → CloudWatch Logs: este walkthrough assume que o CloudTrail está configurado em uma conta de auditoria centralizada, registrando eventos de toda a organização AWS e entregando logs para o CloudWatch Logs. Eu estou usando o log group padrão do Control Tower
aws-controltower/CloudTrailLogsemeu-west-1. Este padrão pode ser adaptado para qualquer caso de uso do CloudWatch Logs. Substitua o nome do log group e as permissões IAM para corresponder ao seu setup.
IAM Role
Tanto o modo Public quanto o modo VPC requerem uma execution role. A role precisa de duas coisas: uma trust policy permitindo que o AgentCore a assuma, e permissões para o que o código do sandbox precisar acessar. Para este walkthrough eu estou usando a policy gerenciada pela AWS ReadOnlyAccess, que cobre o CloudWatch Logs e todas as outras APIs de leitura. Em produção você limitaria o escopo apenas aos serviços que o sandbox realmente precisa.
Trust policy (trust-policy.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock-agentcore.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Opção A: Criar via AWS CLI
# Create the role with the trust policy
aws iam create-role \
--role-name AgentCoreTroubleshootingRole \
--assume-role-policy-document file://trust-policy.json
# Attach the AWS managed ReadOnlyAccess policy
aws iam attach-role-policy \
--role-name AgentCoreTroubleshootingRole \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Opção B: Criar via AWS Console
- Abra o IAM Console e navegue até Roles → Create role.
- Em Trusted entity type, selecione Custom trust policy e cole o JSON da trust policy acima.
- Clique em Next. Na página Add permissions, busque por
ReadOnlyAccesse selecione a policy gerenciada pela AWS. - Nomeie a role como
AgentCoreTroubleshootingRolee clique em Create role.
O modelo de segurança aqui é importante: mesmo com ReadOnlyAccess, o sandbox não pode modificar nenhum recurso. Ele pode ler logs, descrever infraestrutura e listar recursos, mas não pode criar, atualizar ou deletar nada. Para um controle mais rígido em produção, substitua ReadOnlyAccess por uma policy customizada com escopo limitado apenas às APIs e recursos específicos que você precisa (ex: logs:StartQuery, logs:GetQueryResults, logs:DescribeLogGroups no seu log group do CloudTrail).
Usuário IAM para usar o Skill a partir do Claude Code
O binário Go empacotado no plugin do Claude Code precisa de credenciais AWS para chamar a API do AgentCore Code Interpreter (iniciar sessões, executar código, parar sessões). Crie um usuário IAM dedicado com apenas as permissões necessárias.
- Abra o IAM Console e navegue até Users → Create user.
- Digite
code-interpreter-usercomo o nome do usuário. Não habilite o acesso ao console. Clique em Next. - Selecione Attach policies directly. Clique em Create policy (isso abre em uma nova aba).
- Mude para a aba JSON e cole a seguinte policy (certifique-se de substituir AWS_REGION, AWS_ACCOUNT_ID e CODE_INTERPRETER_ID pelos valores relacionados ao Code Interpreter que você criou no passo anterior):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock-agentcore:StartCodeInterpreterSession",
"bedrock-agentcore:InvokeCodeInterpreter",
"bedrock-agentcore:StopCodeInterpreterSession"
],
"Resource": "arn:aws:bedrock-agentcore:<AWS_REGION>:<AWS_ACCOUNT_ID>:code-interpreter-custom/<CODE_INTERPRETER_ID>"
}
]
}
- Clique em Next. Nomeie a policy como
AgentCoreCodeInterpreterAccesse clique em Create policy. - Retorne à aba Create user. Clique no botão de atualizar ao lado da lista de policies, busque por
AgentCoreCodeInterpreterAccess, selecione-a e clique em Next. - Revise e clique em Create user.
- Selecione o usuário recém-criado, vá para a aba Security credentials e clique em Create access key.
- Selecione Command Line Interface (CLI) como o caso de uso, confirme o reconhecimento e clique em Next → Create access key.
- Copie o Access key ID e o Secret access key. Você não poderá ver o secret novamente.
Agora configure um profile AWS nomeado na sua máquina:
aws configure --profile code-interpreter
Digite o access key ID e o secret access key quando solicitado. Defina a região padrão para a região onde você fez deploy do Code Interpreter e o formato de saída como json (ou deixe em branco).
Para usar este profile com o binário Go, defina a variável de ambiente:
export CUSTOM_AGENTCORE_AWS_PROFILE=code-interpreter
Não se preocupe em configurar isso agora. Eu abordo isso mais adiante neste post quando junto tudo.
Quick-Start: Criando o Code Interpreter em Modo Public (Apenas para Experimentação)
Aviso: O modo Public dá ao Code Interpreter acesso total à internet sem isolamento de rede. Não use isso para workloads de produção ou com dados sensíveis. Para produção, use o modo VPC conforme descrito na próxima seção.
Se você não tem uma VPC com subnets privadas e quer experimentar rapidamente, você pode criar um Code Interpreter em modo Public.
Via CLI
export AWS_REGION=eu-west-1
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws bedrock-agentcore-control create-code-interpreter \
--name "aws_troubleshooting" \
--execution-role-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:role/AgentCoreTroubleshootingRole" \
--network-configuration '{"networkMode": "PUBLIC"}'
Via AWS Console
- Abra o console do Amazon Bedrock AgentCore e navegue até Code Interpreters → Create code interpreter.
- Digite
aws_troubleshootingcomo o nome. - Em Execution role, selecione Use an existing role e escolha
AgentCoreTroubleshootingRole. - Em Network configuration, selecione Public.
- Clique em Create code interpreter.
Isso não requer subnets, security groups ou VPC endpoints. O sandbox pode acessar a internet e as APIs da AWS diretamente. Pule para O Binário Go se você está usando o modo Public.
Criando o Code Interpreter em Modo VPC (Recomendado para Produção)
Primeiro, eu criei um recurso Code Interpreter configurado para modo VPC. Isso requer subnets privadas em pelo menos duas availability zones e um security group.
Certifique-se de substituir os IDs das subnets e do security group pelos IDs dos seus próprios recursos.
Via CLI
export AWS_REGION=eu-west-1
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws bedrock-agentcore-control create-code-interpreter \
--name "aws_troubleshooting" \
--execution-role-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:role/AgentCoreTroubleshootingRole" \
--network-configuration '{
"networkMode": "VPC",
"networkModeConfig": {
"subnets": ["subnet-0a1b2c3d4e5f6a7b8", "subnet-9a8b7c6d5e4f3a2b1"],
"securityGroups": ["sg-0123456789abcdef0"]
}
}'
Via AWS Console
- Abra o console do Amazon Bedrock AgentCore e navegue até Code Interpreters → Create code interpreter.
- Digite
aws_troubleshootingcomo o nome. - Em Execution role, selecione Use an existing role e escolha
AgentCoreTroubleshootingRole. - Em Network configuration, selecione VPC.
- Selecione pelo menos duas subnets em availability zones diferentes (devem ser subnets privadas).
- Selecione um security group que permita tráfego de saída para os VPC endpoints que você criará no próximo passo.
- Clique em Create code interpreter.
A resposta (ou a página de detalhes no console) inclui um codeInterpreterIdentifier que eu usarei em todas as chamadas de API subsequentes.
O Binário Go
O CLI agentcore-sandbox encapsula a API do AgentCore Code Interpreter em um único binário que gerencia o ciclo de vida das sessões, execução de código em múltiplos runtimes e streaming de saída. O código fonte completo e as instruções de build estão em bedrock-agentcore-code-interpreter-cli.
Configuração
Defina as seguintes variáveis de ambiente:
| Variável | Obrigatória | Descrição |
|---|---|---|
CUSTOM_AGENTCORE_INTERPRETER_ID | Sim | Identificador do code interpreter |
CUSTOM_AGENTCORE_AWS_PROFILE | Não | Profile de configuração compartilhada da AWS |
CUSTOM_AGENTCORE_AWS_REGION | Não | Override da região AWS |
Uso
agentcore-sandbox <command> [flags] [args...]
Comandos:
| Comando | Descrição |
|---|---|
start | Inicia uma nova sessão, imprime o session ID |
stop <session-id> | Para uma sessão existente |
exec <session-id> [flags] <code> | Executa código ou um comando em uma sessão existente |
run [flags] <code> | One-shot: inicia uma sessão, executa e depois para |
Flags:
| Flag | Valores | Padrão | Aplica-se a |
|---|---|---|---|
--lang | python, javascript/js, typescript/ts | python | exec, run |
--cmd | exec, run | ||
--runtime | nodejs, deno, python | auto | exec, run |
--clear-context | exec, run | ||
--json | start, exec, run | ||
--timeout | seconds | 900 | start, run |
--lang e --cmd são mutuamente exclusivos. Use --cmd para comandos shell, --lang para execução de código. Quando --runtime é omitido, o padrão é python para Python e deno para JavaScript/TypeScript.
Execução one-shot (gerencia o ciclo de vida da sessão automaticamente):
# Python (default language)
agentcore-sandbox run 'print("hello")'
# JavaScript
agentcore-sandbox run --lang js 'console.log("hello")'
# Shell command
agentcore-sandbox run --cmd 'ls -la'
# JSON output for programmatic consumption
agentcore-sandbox run --json --lang python 'print(42)'
Workflow baseado em sessão (a sessão persiste entre chamadas):
# Start a session with a 30-minute timeout
SESSION=$(agentcore-sandbox start --timeout 1800)
# Execute multiple commands in the same session (context is preserved)
agentcore-sandbox exec $SESSION --lang ts 'const x = 1'
agentcore-sandbox exec $SESSION --lang ts 'console.log(x)'
# Clear context and start fresh within the same session
agentcore-sandbox exec $SESSION --clear-context --lang ts 'console.log("fresh start")'
# Stop the session when done
agentcore-sandbox stop $SESSION
Quando --json é passado, a saída é um único objeto JSON no stdout:
{
"stdout": "hello\n",
"stderr": "",
"exitCode": 0,
"executionTime": 123.4,
"isError": false
}
O Plugin do Claude Code
O plugin empacota o binário Go e uma definição de skill em uma estrutura que o Claude Code pode descobrir e usar. O diretório bin/ do plugin contém o binário pré-compilado, que o Claude Code adiciona automaticamente ao PATH da ferramenta Bash quando o plugin está habilitado, então não são necessários caminhos completos. Junto com ele, um arquivo de skill (SKILL.md) ensina ao Claude quando e como invocar o binário: ele descreve o ciclo de vida da sessão (start, execute, stop), documenta o ambiente disponível (boto3, pandas, numpy pré-instalados) e restringe o skill a executar apenas comandos agentcore-sandbox via a diretiva allowed-tools. Isso significa que o Claude não pode executar comandos Bash arbitrários enquanto o skill está ativo. Ele só pode chamar o binário do sandbox.
O resultado é um comando /code-interpreter-execute que os usuários podem invocar naturalmente (ex: /code-interpreter-execute query CloudTrail for role creation events). O Claude lê o skill, escreve o código Python apropriado, gerencia a sessão e faz streaming dos resultados de volta. O código fonte completo do plugin, incluindo a definição do skill, o manifesto do plugin e a lógica de detecção de plataforma, está disponível em aws-bedrock-agentcore-codeinterpreter.
Testes
Distribuição do Plugin
Eu publiquei o plugin em um repositório de marketplace em my2centsai-blog-samples-marketplace. Qualquer pessoa pode instalá-lo com estes comandos:
claude plugin marketplace add fabiodouek/my2centsai-blog-samples-marketplace
claude plugin install aws-bedrock-agentcore-codeinterpreter@my2centsai-blog-samples
Após a instalação, o binário agentcore-sandbox está no PATH e o skill /code-interpreter-execute está disponível. Os usuários precisam de suas próprias credenciais AWS e um recurso Code Interpreter configurado na sua conta.
Configurando Variáveis de Ambiente e Iniciando o Claude Code
Antes de iniciar o Claude Code, defina as seguintes variáveis de ambiente. O profile code-interpreter foi criado anteriormente usando um usuário IAM. Se você está rodando seu workload na AWS (ex: em uma instância EC2), você pode usar uma IAM role em vez disso.
# AWS profile for the Code Interpreter IAM user
export CUSTOM_AGENTCORE_AWS_PROFILE=code-interpreter
# Region where you deployed Code Interpreter
export CUSTOM_AGENTCORE_AWS_REGION=eu-west-1
# Your Code Interpreter ID (replace the suffix with your own)
export CUSTOM_AGENTCORE_INTERPRETER_ID=aws_troubleshooting-nnffwDidWx
Com essas variáveis configuradas, inicie o Claude Code normalmente.
Consultando Logs do CloudTrail a partir do Sandbox
O teste real: o Claude consegue usar este plugin para consultar logs do CloudTrail armazenados no CloudWatch Logs Insights? Eu invoquei o skill:
/code-interpreter-execute query the last 24 hours of CloudTrail logs, i want to have an aggregated view of access denied. My CloudTrail Logs are in the CloudWatch Log Group: aws-controltower/CloudTrailLogs
Nos bastidores, o Claude Code gerou código Python para consultar o CloudWatch Logs, que foi executado pelo Bedrock AgentCore Code Interpreter. Dependendo da solicitação, ele também poderia invocar o AWS CLI diretamente a partir do Code Interpreter. Aqui estão os resultados:

Veredito
O AgentCore Code Interpreter em modo VPC cumpre a promessa de execução de código segura e isolada. A cobrança por segundo sem custos de ociosidade torna-o prático para uso interativo através do Claude Code. Uma query de 45 segundos custa menos de um centavo.
O binário Go empacotado no plugin do Claude Code facilita a invocação das APIs do Bedrock AgentCore Code Interpreter. Sem dependência de versões específicas do AWS CLI nas máquinas clientes, nem dependências de libraries. Ele também permite um controle mais avançado, descarregando a lógica no Skill.
O modelo de plugin do Claude Code é bem adequado para este padrão. O diretório bin/ para empacotar executáveis e allowed-tools para restringir o que o skill pode fazer são exatamente as abstrações certas. A distribuição via marketplace significa que qualquer pessoa do time pode instalar o plugin e começar a executar código sandboxed sem entender o setup do AgentCore por baixo.
O skill entregue no plugin é genérico, e por essa razão você precisa especificar, por exemplo, como recuperar dados do CloudTrail via um CloudWatch Log Group específico. No entanto, você pode ajustar o Skill para atender ao seu caso de uso, ou até definir múltiplos Skills, para diferentes serviços/casos de uso AWS.
Embora o exemplo aqui seja simples, há um enorme benefício em isolar as chamadas de API AWS em um ambiente sandbox: permissões restritas e egress de rede (no modo VPC).
O código fonte do binário Go está em bedrock-agentcore-code-interpreter-cli e o plugin do Claude Code está em aws-bedrock-agentcore-codeinterpreter.