Example: Add an integration to an existing collection agent with Claude
Connect a MySQL database to Monte Carlo from Claude through an AWS collection agent you already run, with credentials in your own AWS Secrets Manager. The only step on your side is an IAM policy.
This example adds a MySQL database to Monte Carlo through an AWS collection agent that is already deployed and registered. Don't have one yet? Start with Create and register an AWS collection agent with Terraform (or with the AWS CLI). At the end you have:
- a MySQL connection, validated, on the agent you already run: no new deployment;
- credentials that stay in your AWS Secrets Manager: Monte Carlo stores only the secret's ARN.
| Who | What | How |
|---|---|---|
| You | Store the MySQL credentials | AWS CLI, in Secrets Manager |
| Claude | Find the existing agent and check that MySQL can be connected through it | MCP tools |
| You | Let the agent read the new secret | AWS CLI, one IAM inline policy |
| Claude | Check the secret through the agent, create credentials, warehouse and connection, validate | MCP tools |
Before you start
- Claude with the Agent Toolkit plugin, signed in to the Monte Carlo MCP server. See Agent Toolkit.
- A registered AWS collection agent that can reach the database: same VPC, or a network route, and a security group rule for the database port (3306 for MySQL).
- A MySQL user with the grants in MySQL, and at least one table.
- The AWS CLI signed in to the agent's AWS account, with permission to edit IAM role policies.
1. Store the credentials in AWS Secrets Manager
The agent expects the MySQL keys under connect_args. The password is read from a hidden prompt and passed to jq through the environment, so it isn't shown, saved in your shell history, or visible in the process list:
REGION=<region>
read -r -s -p "MySQL password: " MYPASS; echo
MYPASS="$MYPASS" jq -n \
--arg host "<mysql-host>" --argjson port 3306 --arg user "<monte-carlo-user>" \
'{connect_args: {host: $host, port: $port, user: $user, password: $ENV.MYPASS}}' \
| aws secretsmanager create-secret --region "$REGION" \
--name mc/mysql --secret-string file:///dev/stdin \
--query ARN --output text
unset MYPASSIn zsh, replace the read line with read -r -s "MYPASS?MySQL password: ". The command prints only the secret's ARN.
2. Ask Claude
/monte-carlo-onboarding add our MySQL database through our existing AWS agent; the credentials are in AWS Secrets Manager
Claude reads your account before asking anything. In this example it reported:
- the existing agent (
COLLECTION_AGENTon AWS, enabled) with the warehouses and connections already on it; - that no MySQL warehouse, connection or credentials exist yet;
- that MySQL can be connected through that agent with a Secrets Manager reference, so no new deployment is needed.
It then lists what it still needs, without filling anything in with guesses: the secret ARN and region, whether the agent reads it directly or assumes a role, confirmation of the secret's keys, network reach and grants, and the warehouse and connection names.
3. Answer Claude's questions
Answer with references and names only, never the password:
- Secret: arn:aws:secretsmanager:<region>:<account-id>:secret:mc/mysql-AbCdEf (region <region>). It has host, port, user and password under connect_args.
- The agent reads it directly, no assumable role. The agent's role doesn't have access to this secret yet: give me the AWS CLI commands to add it, keeping the access it already has.
- MySQL is in the same VPC and private subnets as the agent, and its security group allows 3306 from the VPC. The user has the grants.
- Warehouse name: mysql-prod. Connection name: mysql-prod-conn.
Go ahead once I confirm the IAM change is done.
4. Let the agent read the new secret
Claude gives you these commands. They add a separate inline policy scoped to the new secret, so the agent's existing grants are left untouched:
SECRET_ARN='<mysql-secret-arn>'
# 1. Find the agent's execution role from its Lambda function
ROLE_ARN=$(aws lambda get-function-configuration \
--region "$REGION" \
--function-name <agent-lambda-function-name> \
--query Role --output text)
ROLE_NAME=${ROLE_ARN##*/}
# 2. See the current grants. put-role-policy replaces an inline policy with the same name,
# so pick a name that isn't listed.
aws iam list-role-policies --role-name "$ROLE_NAME"
aws iam list-attached-role-policies --role-name "$ROLE_NAME"
# 3. Which KMS key encrypts the secret (metadata only, not the value)
aws secretsmanager describe-secret --region "$REGION" --secret-id "$SECRET_ARN" \
--query KmsKeyId --output text
# 4. Allow the agent to read the new secret
aws iam put-role-policy \
--role-name "$ROLE_NAME" \
--policy-name mc-agent-read-mysql-secret \
--policy-document "{
\"Version\": \"2012-10-17\",
\"Statement\": [{
\"Sid\": \"ReadMySQLSecret\",
\"Effect\": \"Allow\",
\"Action\": \"secretsmanager:GetSecretValue\",
\"Resource\": \"$SECRET_ARN\"
}]
}"
# 5. Check the grant: expect "allowed"
aws iam simulate-principal-policy \
--policy-source-arn "$ROLE_ARN" \
--action-names secretsmanager:GetSecretValue \
--resource-arns "$SECRET_ARN" \
--query 'EvaluationResults[0].EvalDecision' --output textThe agent's Lambda function name is the FunctionArn output of its CloudFormation stack, or mcd_agent_function_arn of the Terraform module.
- If step 3 prints a customer-managed key ARN (not
Noneand notalias/aws/secretsmanager), also allowkms:Decrypton that key, ideally with akms:ViaServicecondition forsecretsmanager.<region>.amazonaws.com. - Don't test access with
aws secretsmanager get-secret-value: it prints the password. Claude's next check tests the agent's access without showing the value. - If the agent's stack is managed by Terraform or CloudFormation, add the policy there too, or the next apply may remove it.
Tell Claude the result of step 5.
5. Claude finishes the onboarding
| Step | MCP tool |
|---|---|
| Test-read the secret through the agent before saving anything | validate_aws_secrets_manager_credentials, get_validation_run |
| Save the secret reference (ARN only) | create_aws_secrets_manager_credentials |
| Create the warehouse | create_warehouse with connection_type: mysql |
| Create the connection with the default jobs | create_connection |
| Validate the connection | validate_connection, get_validation_run |
The run ends with a summary like this one. Resources it reused are kept out of cleanup, because other connections depend on them:
Created in this run
credentials <id> mysql aws_secrets_manager
warehouse <id> mysql-prod
connection <id> mysql-prod-conn job_types=metadata,sql_query
validation <id> passed 5/5 passed
Reused (excluded from cleanup)
deployment <id> COLLECTION_AGENT/AWS enabled=true
agent <id>
Changed on your side (AWS)
inline policy mc-agent-read-mysql-secret on the agent's execution role
Cleanup if you abandon this: delete_connection → delete_warehouse →
delete_aws_secrets_manager_credentials. Keep the deployment and agent.
Remove the IAM inline policy separately in AWS.
Collection starts on its own; the first metadata appears within about an hour.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| The secret check fails with "Could not connect" | The agent can't read the secret. Re-run step 5; if it isn't allowed, check the policy's Resource ARN and, for a customer-managed KMS key, kms:Decrypt. |
| The secret check connects but fails Tables | The user lacks grants, or the database has no tables yet. Apply the grants in MySQL, then ask Claude to re-check. |
| The connect check times out | The agent can't reach the database. Check the route from the agent's subnets and the database security group's inbound rule on 3306. |
| Access worked, then broke after a stack update | The inline policy was added by hand and removed by Terraform or CloudFormation. Add it to the stack's code. |
Updated about 1 hour ago
