Install any skill in seconds. Free to start, no credit card required.
Get Started Free →butterbase-ai/storage
Use when uploading or downloading files, generating presigned URLs, configuring storage ACLs, or persisting file references (avatars, attachments, images) in a Butterbase app
Passed 22 of 22 test cases with the skill, and 10 of 22 without it.
and 11 more in the full report
12 fixed10 passed either way0 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 12 test cases the skill fixed. Same model, same prompt, with and without the skill.
If a Butterbase app configured with an allowed content types whitelist receives an upload request for an unapproved MIME type `application/x-executable`, what error code is returned?
| Checked | Without skill | With skill |
|---|---|---|
| The response specifies the VALIDATION_INVALID_TYPE error code. | Missed | Passed |
The instructions your model reads when the skill loads.
Butterbase stores files in S3 (or LocalStack in dev) and exposes them via presigned URLs. Every file gets a stable object_id (UUID) that you persist in your tables; URLs are generated on demand and expire.
All storage operations go through one tool: manage_storage with an action parameter.
| Action | Purpose |
|---|---|
upload_url | Generate a 15-minute presigned PUT URL and reserve an object_id |
download_url | Generate a 1-hour presigned GET URL for a stored object |
list | List objects (scoped by caller's role) |
delete | Permanently remove an object from S3 + database |
update_config | Toggle app-level publicReadEnabled and other storage settings |
object_id vs s3_key| Field | What it is | When you use it |
|---|---|---|
object_id | UUID, stable, app-level handle | Persist in your tables (e.g. users.avatar_id, posts.image_id) |
s3_key | Internal bucket path like app_abc/user_uuid/file.jpg | Internal only — never treat this as a URL |
Critical: s3_key is not a URL. You cannot use it as <img src> or <a href>. Always store the object_id and resolve a fresh download URL at render time.
A single upload is two HTTP calls and one DB insert in your app:
┌─────────────────────────┐
│ 1. manage_storage( │ → returns { upload_url, object_id, expires_at }
│ action: upload_url)│
├─────────────────────────┤
│ 2. PUT file -> S3 │ → must include exact Content-Type header
├─────────────────────────┤
│ 3. INSERT INTO ... │ → save object_id alongside the user/post/etc.
└─────────────────────────┘
test cases passed, vs 10 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.