skills/s3-files-skill/skills/s3-files/SKILL.md
Upload and share files via Amazon S3 with time-limited pre-signed URLs. Generate download links, create upload pages for receiving files, and manage secure file sharing without exposing S3 buckets publicly.
npx skillsauth add aws-samples/sample-openclaw-on-aws-with-bedrock s3-filesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Upload and share files via Amazon S3 with automatic expiration and clean download filenames.
| Command | Purpose |
|---------|---------|
| node upload.js <file-path> | Upload file and get download link |
| node download-url.js <s3-key> | Generate download URL for existing file |
| node generate-upload-page.js [max-size-mb] | Create upload page for receiving files |
cd ~/.openclaw/workspace/skills/s3-files
node upload.js /path/to/file.pdf
Output:
Example:
📤 Uploading report.pdf...
✅ Upload complete!
📁 S3 Key: uploads/1772120357022-report.pdf
📥 Download as: report.pdf
🔗 Download URL (24h):
https://bucket.s3.amazonaws.com/uploads/1772120357022-report.pdf?...&response-content-disposition=attachment%3B%20filename%3D%22report.pdf%22
For files already in S3:
node download-url.js uploads/1234567890-file.zip [hours]
Parameters:
s3-key: Full S3 key (e.g., uploads/1234567890-file.zip)hours: Optional expiration in hours (default: 24)Generate a web page for others to upload files to your S3 bucket:
node generate-upload-page.js 50 # Max 50MB upload
Output:
upload-{timestamp} in S3Use case: Share the page URL with someone who needs to send you files.
Copy config.example.json to config.json:
{
"bucketName": "your-bucket-name",
"region": "us-west-2",
"defaultExpirationHours": 24,
"maxUploadSizeMB": 100
}
Required IAM Permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
Storage (S3 key):
uploads/1772120357022-report.pdfDownload (browser):
Content-Disposition header to suggest clean filenamereport.pdf (no timestamp)Technical:
// S3 key has timestamp
const key = "uploads/1772120357022-report.pdf";
// Download URL includes Content-Disposition
ResponseContentDisposition: 'attachment; filename="report.pdf"'
// Result: Browser saves as "report.pdf"
All downloads use AWS S3 pre-signed URLs:
Bucket Configuration
IAM Permissions
arn:aws:s3:::bucket-name/*Input Validation
Expiration
Rate Limiting
Error: "File not found"
Error: "Failed to generate download URL"
Error: "Rate limit exceeded"
Upload page not loading
node upload.js file.pdf uploads/custom-name.pdf
node download-url.js uploads/file.zip 48 # 48 hours
const { uploadFile } = require('./upload.js');
const { generateDownloadUrl } = require('./download-url.js');
// Upload
const { key, downloadUrl } = await uploadFile('/path/to/file.pdf');
// Generate URL
const url = await generateDownloadUrl(key, 24);
s3-files/
├── upload.js # Upload files and get download links
├── download-url.js # Generate pre-signed download URLs
├── generate-upload-page.js # Create upload pages for others
├── config.example.json # Configuration template
└── package.json # Node.js dependencies
{
"@aws-sdk/client-s3": "^3.x",
"@aws-sdk/s3-request-presigner": "^3.x",
"@aws-sdk/s3-presigned-post": "^3.x"
}
Install with:
npm install
Scenario: Share a log file with a colleague for 6 hours
# 1. Upload the file
node upload.js /var/log/app.log
# Output includes download URL
# 📥 Download as: app.log
# 🔗 Download URL (24h): https://...
# 2. Send URL to colleague (they download as "app.log")
# 3. URL expires in 24 hours automatically
Scenario: Receive a file from someone
# 1. Generate upload page
node generate-upload-page.js 100
# Output:
# 📄 Page URL (24h expiration): https://...
# 📦 Files will be uploaded to S3 with key: upload-1234567890
# 2. Send page URL to person
# 3. They upload file via browser
# 4. Generate download URL for the uploaded file
node download-url.js upload-1234567890
S3 Pricing (us-west-2 example):
Typical costs for file sharing:
Total: < $1/month for moderate use
Always ask before uploading files
Share URLs responsibly
Clean up old files
Respect rate limits
Verify before generating upload pages
tools
# EventBridge Cron — Scheduled Tasks Schedule recurring tasks via Amazon EventBridge Scheduler. Tasks execute at the specified time and deliver results to the user's chat channel. ## Usage ```bash node /skills/eventbridge-cron/tool.js '<JSON>' ``` ## Actions ### Create a schedule ```json {"action":"create", "cron_expression":"cron(0 9 * * ? *)", "timezone":"Asia/Shanghai", "message":"Check email and summarize unread messages", "schedule_name":"Daily email check"} ``` ### List all schedules
tools
Spawn Kiro CLI via background process for code-related tasks. Use when user mentions "kiro", "kiro-cli", or needs to work with code — writing, modifying, reading, analyzing, reviewing, debugging, explaining, or understanding codebases. This includes building features, fixing bugs, refactoring, writing tests, code review, and exploring unfamiliar code.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------