Example: Create and register an AWS collection agent with the AWS CLI and Claude
Deploy a Monte Carlo collection agent in your AWS account with the AWS CLI and CloudFormation, and let Claude create and register it in Monte Carlo. Integrations are connected to it later.
A collection agent runs in your AWS account, so connections originate from your network and credentials can stay in your own secret store. This example creates one and registers it with Monte Carlo, without connecting any integration yet. It's the route for teams that don't use Terraform: with Terraform, one configuration does all of this, see Create and register an AWS collection agent with Terraform. The other examples connect integrations to an agent like this one:
- Onboard Postgres and Snowflake with self-hosted credentials
- Add an integration to an existing collection agent
| Who | What | How |
|---|---|---|
| Claude | Create the agent deployment and read its External ID | create_deployment, get_deployment |
| You | Deploy the agent in your AWS account | AWS CLI, Monte Carlo's CloudFormation template |
| Claude | Register the agent and confirm it's enabled | register_aws_collection_agent, get_deployment |
Before you start
- Claude with the Agent Toolkit plugin, signed in to the Monte Carlo MCP server. See Agent Toolkit.
- A Monte Carlo user who can manage integrations, and the Collection AWS account ID from Settings → Account information. This is Monte Carlo's account ID, not yours.
- The AWS CLI signed in to the account the agent will run in, with permission to create CloudFormation stacks and IAM roles.
- For databases inside a VPC: at least two private subnets that can reach them and that have outbound internet access through NAT. The agent reaches your databases from these subnets and Monte Carlo through NAT. Without a VPC, the agent reaches only publicly accessible endpoints.
1. Ask Claude
/monte-carlo-onboarding we need a Monte Carlo collection agent in our AWS account; we'll connect databases to it later
Claude first reads your account. If you already have an enabled AWS agent, it asks whether to reuse it: a second agent is only needed for a different AWS account, region, or a network the first one can't reach. It then asks for:
- the AWS region the agent runs in;
- whether the databases are reached through a VPC, and which private subnets;
- an optional name for the deployment and agent;
- how you want to deploy: AWS CLI with CloudFormation, the Terraform module, or a complete Terraform file.
2. Answer Claude's questions
A new AWS agent.
- Region: <region>, AWS account <account-id>.
- Network: private subnets <subnet-a> and <subnet-b> in VPC <vpc-id> (both have NAT).
- Name: <agent-name>.
- Collection AWS account ID from the Account information page: <collection-aws-account-id>.
- Create the deployment now, and give me AWS CLI commands to deploy it with the CloudFormation template.
Claude creates the deployment, which shows enabled: false until the agent is registered, and gives you its External ID.
3. Deploy the agent
Claude gives you these commands with your values filled in. The parameters go in a JSON file, which keeps the comma inside the subnet list intact and survives copy-paste from a terminal:
REGION=<region>
STACK=mcd-agent-<agent-name>
# 1. Check you're in the account the agent should run in
aws sts get-caller-identity --query Account --output text
# 2. Stack parameters
cat > mcd-agent-params.json <<'EOF'
[
{"ParameterKey": "ExternalId", "ParameterValue": "<external-id-from-claude>"},
{"ParameterKey": "CloudAccountId", "ParameterValue": "<collection-aws-account-id>"},
{"ParameterKey": "ExistingVpcId", "ParameterValue": "<vpc-id>"},
{"ParameterKey": "ExistingSubnetIds", "ParameterValue": "<subnet-a>,<subnet-b>"}
]
EOF
# 3. Create the stack
aws cloudformation create-stack \
--region "$REGION" \
--stack-name "$STACK" \
--template-url https://mcd-public-resources.s3.amazonaws.com/cloudformation/aws_apollo_agent.yaml \
--parameters file://mcd-agent-params.json \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
# 4. Wait for it (a few minutes)
aws cloudformation wait stack-create-complete --region "$REGION" --stack-name "$STACK"
# 5. Read the outputs Claude needs
aws cloudformation describe-stacks --region "$REGION" --stack-name "$STACK" \
--query "Stacks[0].Outputs[?OutputKey=='FunctionArn' || OutputKey=='InvocationRoleArn' || OutputKey=='InvocationRoleExternalId' || OutputKey=='SecurityGroupId']" \
--output tableLeave out ExistingVpcId and ExistingSubnetIds if the agent doesn't need to run in a VPC. The stack also creates an encrypted S3 bucket for the agent and a security group with outbound access only. See Create and register an AWS agent for the template's other parameters.
If the stack fails, the first failed resource explains why:
aws cloudformation describe-stack-events --region "$REGION" --stack-name "$STACK" \
--query "StackEvents[?ResourceStatus=='CREATE_FAILED'].[LogicalResourceId,ResourceStatusReason]" \
--output table4. Claude registers the agent
Send Claude the FunctionArn and InvocationRoleArn, and check that InvocationRoleExternalId matches the External ID it gave you. None of these are secrets. Claude registers the agent with register_aws_collection_agent: Monte Carlo reaches your Lambda function through the invocation role, and the deployment switches to enabled: true.
The run ends with a summary like this one:
Created in this run
deployment <id> <agent-name> COLLECTION_AGENT/AWS enabled=true
agent <id> <agent-name> AWS_ASSUMABLE_ROLE enabled=true
Pending on your side
- Per database, later: allow the agent's security group on the database's port; store the
credentials in Secrets Manager, readable by the agent's execution role; then ask Claude to connect it
Cleanup if you abandon this: delete_aws_collection_agent → delete_deployment, then
aws cloudformation delete-stack (empty the agent's S3 bucket first)
Before you connect a database
For each database you connect to this agent later:
- Network: allow inbound traffic from the agent's security group (the
SecurityGroupIdoutput) on the database's port. - Credentials: store the database login in AWS Secrets Manager in the format in Self-hosted credentials, and allow the agent's execution role
secretsmanager:GetSecretValueon it. The execution role is the stack'sExecutionRoleresource. - Ask Claude to connect it, giving only the secret's name or ARN. See Add an integration to an existing collection agent.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
create-stack fails with S3 error: Access Denied, or a value is split across lines | A long line wrapped when it was copied. Keep the parameters in the JSON file as shown. |
| Registration fails with "Could not connect to Agent" | The stack was created with the wrong Collection AWS account ID (for example your own account ID) or External ID. Check both against Settings → Account information and Claude's External ID, update the stack, and ask Claude to register again. |
| Registration works, but connections later time out | The agent's subnets have no route to the database or no NAT, or the database's security group doesn't allow the agent's security group. |
Updated about 1 hour ago
