| name | aws |
| description | Emulated AWS cloud services (S3, SQS, IAM, STS) for local development and testing. Use when the user needs to interact with AWS API endpoints locally, test S3 bucket and object operations, emulate SQS queues and messages, manage IAM users/roles/access keys, test STS assume role, or work without hitting real AWS APIs. Triggers include "AWS emulator", "emulate AWS", "mock S3", "local SQS", "test IAM", "emulate S3", "AWS locally", "STS assume role", or any task requiring local AWS service emulation. |
| allowed-tools | Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*) |
AWS Emulator
S3, SQS, IAM, and STS emulation with AWS SDK-compatible S3 paths and query-style SQS/IAM/STS endpoints. All state is in-memory, and responses use AWS-compatible XML.
Start
npx emulate --service aws
Or programmatically:
import { createEmulator } from 'emulate'
const aws = await createEmulator({ service: 'aws', port: 4006 })
Auth
Pass tokens as Authorization: Bearer <token>. Scoped permissions use s3:*, sqs:*, iam:*, sts:* patterns.
curl http://localhost:4006/ \
-H "Authorization: Bearer test_token_admin"
Pointing Your App at the Emulator
Environment Variable
AWS_EMULATOR_URL=http://localhost:4006
AWS SDK v3
import { S3Client } from '@aws-sdk/client-s3'
const s3 = new S3Client({
endpoint: process.env.AWS_EMULATOR_URL,
region: 'us-east-1',
credentials: {
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
},
forcePathStyle: true,
})
import { SQSClient } from '@aws-sdk/client-sqs'
const sqs = new SQSClient({
endpoint: `${process.env.AWS_EMULATOR_URL}/sqs`,
region: 'us-east-1',
credentials: {
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
},
})
import { IAMClient } from '@aws-sdk/client-iam'
const iam = new IAMClient({
endpoint: `${process.env.AWS_EMULATOR_URL}/iam`,
region: 'us-east-1',
credentials: {
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
},
})
Seed Config
aws:
region: us-east-1
s3:
buckets:
- name: my-app-bucket
- name: my-app-uploads
region: eu-west-1
sqs:
queues:
- name: my-app-events
- name: my-app-dlq
visibility_timeout: 60
- name: my-app-orders.fifo
fifo: true
iam:
users:
- user_name: developer
create_access_key: true
- user_name: readonly-user
roles:
- role_name: lambda-execution-role
description: Role for Lambda function execution
assume_role_policy: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
Default seed (always created): S3 bucket emulate-default, SQS queue emulate-default-queue, IAM user admin with access key pair (AKIAIOSFODNN7EXAMPLE / wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY).
API Endpoints
S3
S3 routes use root paths matching the real AWS S3 wire format. Legacy /s3/ prefixed paths are also supported.
curl http://localhost:4006/ \
-H "Authorization: Bearer $TOKEN"
curl -X PUT http://localhost:4006/my-bucket \
-H "Authorization: Bearer $TOKEN"
curl -X DELETE http://localhost:4006/my-bucket \
-H "Authorization: Bearer $TOKEN"
curl -I http://localhost:4006/my-bucket \
-H "Authorization: Bearer $TOKEN"
curl "http://localhost:4006/my-bucket?prefix=uploads/&delimiter=/&max-keys=100" \
-H "Authorization: Bearer $TOKEN"
curl -X PUT http://localhost:4006/my-bucket/path/to/file.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: text/plain" \
-H "x-amz-meta-author: test" \
--data-binary "file contents"
curl http://localhost:4006/my-bucket/path/to/file.txt \
-H "Authorization: Bearer $TOKEN"
curl -I http://localhost:4006/my-bucket/path/to/file.txt \
-H "Authorization: Bearer $TOKEN"
curl -X DELETE http://localhost:4006/my-bucket/path/to/file.txt \
-H "Authorization: Bearer $TOKEN"
curl -X PUT http://localhost:4006/dest-bucket/copy.txt \
-H "Authorization: Bearer $TOKEN" \
-H "x-amz-copy-source: /source-bucket/original.txt"
SQS
All SQS operations use POST /sqs/ with Action as a form-urlencoded parameter.
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "Action=CreateQueue&QueueName=my-queue"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "Action=CreateQueue&QueueName=my-queue&Attribute.1.Name=VisibilityTimeout&Attribute.1.Value=30"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ListQueues"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ListQueues&QueueNamePrefix=my-"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetQueueUrl&QueueName=my-queue"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetQueueAttributes&QueueUrl=<queue_url>"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=SendMessage&QueueUrl=<queue_url>&MessageBody=Hello+World"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=SendMessage&QueueUrl=<queue_url>&MessageBody=Hello&MessageAttribute.1.Name=type&MessageAttribute.1.Value.DataType=String&MessageAttribute.1.Value.StringValue=greeting"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ReceiveMessage&QueueUrl=<queue_url>&MaxNumberOfMessages=5"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=DeleteMessage&QueueUrl=<queue_url>&ReceiptHandle=<receipt_handle>"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=PurgeQueue&QueueUrl=<queue_url>"
curl -X POST http://localhost:4006/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=DeleteQueue&QueueUrl=<queue_url>"
IAM
All IAM operations use POST /iam/ with Action as a form-urlencoded parameter.
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=CreateUser&UserName=new-user"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetUser&UserName=new-user"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ListUsers"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=DeleteUser&UserName=new-user"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=CreateAccessKey&UserName=developer"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ListAccessKeys&UserName=developer"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=DeleteAccessKey&UserName=developer&AccessKeyId=AKIA..."
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=CreateRole&RoleName=my-role&AssumeRolePolicyDocument={}"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetRole&RoleName=my-role"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ListRoles"
curl -X POST http://localhost:4006/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=DeleteRole&RoleName=my-role"
STS
All STS operations use POST /sts/ with Action as a form-urlencoded parameter.
curl -X POST http://localhost:4006/sts/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetCallerIdentity"
curl -X POST http://localhost:4006/sts/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=AssumeRole&RoleArn=arn:aws:iam::123456789012:role/my-role&RoleSessionName=my-session"
Inspector
curl http://localhost:4006/_inspector?tab=s3
curl http://localhost:4006/_inspector?tab=sqs
curl http://localhost:4006/_inspector?tab=iam
Common Patterns
Upload and Retrieve an Object
TOKEN="test_token_admin"
BASE="http://localhost:4006"
curl -X PUT $BASE/my-data \
-H "Authorization: Bearer $TOKEN"
curl -X PUT $BASE/my-data/config.json \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data-binary '{"key": "value"}'
curl $BASE/my-data/config.json \
-H "Authorization: Bearer $TOKEN"
Send and Receive SQS Messages
TOKEN="test_token_admin"
BASE="http://localhost:4006"
QUEUE_URL=$(curl -s -X POST $BASE/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=GetQueueUrl&QueueName=emulate-default-queue" | grep -oP '<QueueUrl>\K[^<]+')
curl -X POST $BASE/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=SendMessage&QueueUrl=$QUEUE_URL&MessageBody=Hello+from+emulate"
curl -X POST $BASE/sqs/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=ReceiveMessage&QueueUrl=$QUEUE_URL&MaxNumberOfMessages=1"
Create IAM User with Access Key
TOKEN="test_token_admin"
BASE="http://localhost:4006"
curl -X POST $BASE/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=CreateUser&UserName=ci-user"
curl -X POST $BASE/iam/ \
-H "Authorization: Bearer $TOKEN" \
-d "Action=CreateAccessKey&UserName=ci-user"