About blink-storage
blink-storage documents Blink storage for developers who need to upload, list, download, or remove application files. It covers paths, access requirements, and upload progress.
Key features
- 01Upload files and get public URLs
- 02List files by path prefix
- 03Create download links with custom names
- 04Remove one or multiple files
- 05Track upload progress
Use cases
- 01Upload an avatar and save its URL
- 02Provide an image to a vision AI
- 03Browse project files by directory
- 04Remove files no longer needed
MCP support
It documents the MCP tools blink_storage_list, blink_storage_url, and blink_storage_delete for listing files, retrieving public CDN URLs, and deleting stored files.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ blink-new/ blink-plugin --skill blink-storageAfter installing, type/blink-storagein Claude Code to confirm it loaded.
Details
From the project READMEMCP Tools
| Tool | Description |
|---|---|
blink_storage_list | List files in project storage with optional path prefix |
blink_storage_url | Get the public CDN URL for a stored file |
blink_storage_delete | Delete a file from storage |
Getting Started
# Upload a file
blink storage upload ./photo.jpg --path uploads/photo.jpg
# List files
blink storage list
# List files in a path
blink storage list uploads/
Auth Requirements
| Operation | Auth Required | Notes |
|---|---|---|
upload() | ❌ No | Public add-only (no overwrite) |
download() | ✅ Yes | Signed URL |
remove() | ✅ Yes | Requires JWT |
Upload
const { publicUrl } = await blink.storage.upload(
file,
`uploads/${Date.now()}.${file.name.split('.').pop()}`,
{ onProgress: (percent) => console.log(`${percent}%`) }
)
SDK auto-detects file type from content and corrects the extension. Uploads are add-only — duplicate paths return 409. Use timestamps or random IDs for uniqueness.
Download
const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg')
window.open(downloadUrl, '_blank')
// Custom filename
const { downloadUrl } = await blink.storage.download('images/photo.jpg', {
filename: 'my-photo.jpg',
})
Remove
await blink.storage.remove('uploads/file1.jpg')
await blink.storage.remove('file1.jpg', 'file2.jpg', 'file3.png') // multiple
Common Patterns
Avatar Upload
const handleAvatarUpload = async (file: File) => {
const { publicUrl } = await blink.storage.upload(
file,
`avatars/${user.id}-${Date.now()}.${file.name.split('.').pop()}`
)
await blink.auth.updateMe({ avatar: publicUrl })
return publicUrl
}
Upload with Progress
const [progress, setProgress] = useState(0)
const handleUpload = async (file: File) => {
const { publicUrl } = await blink.storage.upload(
file,
`documents/${Date.now()}.${file.name.split('.').pop()}`,
{ onProgress: (percent) => setProgress(percent) }
)
return publicUrl
}
For AI Image Input
Upload first to get an HTTPS URL with extension — required for AI vision.
const { publicUrl } = await blink.storage.upload(photo, `photos/${Date.now()}.jpg`)
const { text } = await blink.ai.generateText({
messages: [{ role: "user", content: [
{ type: "text", text: "What's in this image?" },
{ type: "image", image: publicUrl },
]}],
})
URL Format
Uploaded files return direct HTTPS URLs: https://storage.googleapis.com/{project}/uploads/{filename}.{ext} — publicly accessible, HTTPS, with file extension.
Common Errors
| Error | Cause | Fix |
|---|---|---|
| 409 conflict | Path already exists | Add timestamp/random ID |
| Invalid path | Special characters | Sanitize: path.replace(/[^a-zA-Z0-9_\-\/\.]/g, '_') |
| File too large | Exceeds limit | Compress or split file |